RFC 4244
An Extension to the Session Initiation Protocol (SIP) for Request History Information
Network Working Group RFC 4244 π
An Extension to the Session Initiation Protocol (SIP) for Request History Information β¨
Authors: M. Barnes, Ed. (Nortel) π Category: Standards Track πΈ Date: November 2005 π¦ Obsoletes and updates: nothing is listed in this header, so it doesn't replace or update any earlier RFC π«Ά
Status of This Memo π
Okay so this doc is an Internet standards track protocol for the Internet community, and the authors want feedback and suggestions for making it better π§ For the current standardization state and status of this protocol, check the "Internet Official Protocol Standards" (STD 1) listing π And yes, anyone can distribute this memo, no limits π
Copyright Notice β¨
Copyright (C) The Internet Society (2005). π
Abstract π₯
This document is all about a standard way to capture the history information attached to a Session Initiation Protocol (SIP) request π¦ Why does that matter? Because it tells you how and why a call landed at a particular application or user, and that unlocks a ton of enhanced services π The doc defines a brand new optional SIP header called History-Info that records this history inside requests π
Table of Contents π
1. Introduction ....................................................2
1.1. Overview ...................................................2
1.2. Conventions Used in This Document ..........................3
1.3. Background: Why define a Generic "Request History"
capability? ................................................3
2. "Request History" Requirements ..................................4
2.1. Security Requirements ......................................6
2.2. Privacy Requirements .......................................7
3. Request History Information Description .........................7
3.1. Optionality of History-Info ................................8
3.2. Securing History-Info ......................................8
3.3. Ensuring the Privacy of History-Info .......................9
4. Request History Information Protocol Details ....................9
4.1. Protocol Structure of History-Info ........................10
4.2. Protocol Examples .........................................11
4.3. Protocol Usage ............................................12
4.3.1. User Agent Client (UAC) Behavior ...................12
4.3.2. User Agent Server (UAS) Behavior ...................13
4.3.3. Proxy Behavior .....................................13
4.3.4. Redirect Server Behavior ...........................18
4.4. Security for History-Info .................................18
4.5. Example Applications Using History-Info ...................19
4.5.1. Example with Privacy Header for Entire
Request at Proxy2 ..................................21
4.5.2. Example with Privacy Header for Specific
URI (UA4) at Proxy2 ................................22
5. Application Considerations .....................................24
6. Security Considerations ........................................25
7. IANA Considerations ............................................25
7.1. Registration of New SIP History-Info Header ...............25
7.2. Registration of "history" for SIP Privacy Header ..........26
8. Normative References ...........................................26
9. Informative References .........................................26
10. Acknowledgements ..............................................26
11. Contributors' Addresses .......................................27
Appendix. Example Scenarios........................................28
Appendix A. Sequentially forking (History-Info in Response).....28
Appendix B. Voicemail...........................................34
Appendix C. Automatic Call Distribution Example.................39
Appendix D. Session via Redirect and Proxy Servers..............41
1. Introduction π§
1.1. Overview π
Lots of services that SIP is expected to support need to figure out why and how a call got to a specific application π€ Think "click to talk" SIP Uniform Resource Locators (URLs) on a web page that launch sessions into call centers, "call history/logging" features inside smart call management software for SIP User Agents (UAs), and calls going to voicemail servers π SIP already gives you redirect and retarget abilities so calls can be routed to the right app, but there's currently no standard way inside SIP to pass along the history of that request π That "request history" lets the receiving application guess how and why the call showed up, which is honestly so useful π
This document defines a new SIP header, History-Info, to give everyone one standard way to capture request history. That opens the door to a wide variety of services for networks and end-users alike β¨ The History-Info header is basically a building block for new services π¦
Section 1.3 gives extra background on the Request History capability. Section 2 lists the requirements for a solution, and Section 3 gives the big-picture overview of the solution π
Section 4 has the nitty-gritty details of the additions to the SIP protocol π€ Example uses of the new header live in Section 4.5, and more scenarios are in the Appendix π
Section 5 sums up the application considerations from the earlier sections, and Section 6 recaps the security solution π«Ά
1.2. Conventions Used in This Document π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119]. π
1.3. Background: Why define a Generic "Request History" capability? π₯
Okay so SIP already gives you redirect and retarget powers that let calls get routed to specific applications, as defined in [RFC3261] π From here on, this doc uses the word 'retarget' for when a Proxy Server or User Agent Client (UAC) changes a Uniform Resource Identifier (URI) in a request, which changes where that request is going π¦ The reason for picking this word is that we don't want the history to be tied only to the SIP Redirect Server capability. That's the one where a response tells the UAC to retarget the original request to an alternate URI π The rules for working out request targets in Section 16.5 of [RFC3261] fit perfectly with how this document uses the term π
Here's the motivation: when things get retargeted, old routing information can be lost forever π That lost info can be really important history, because it lets the elements the call gets retargeted to handle it in a locally defined, application-specific way π§ This document only proposes a way to transport the request history. It does not propose any application-specific behavior for a Proxy or UA when it receives the info π ββοΈ Honestly, what the recipient does with it should be a local decision for that recipient application π
Plenty of current network applications already let the parties on a call swap extra info about how and why the call was routed to a particular destination πΈ A few examples:
- Web "referral" applications, where an app inside a web server figures out that a visitor came to the site through an "associate" site that earns a "referral" commission for sending that traffic π°
- Email forwarding, where the forwarded-to user gets a "history" of who sent the email to whom and when βοΈ
- Traditional telephony services like voicemail, call-center "automatic call distribution", and "follow-me" style services π
A few of these apps already define their own app-specific ways to get the history they need π«Ά
On top of that, request history could also level up basic SIP functionality in these ways:
- Some diagnostic information for debugging SIP requests. (Heads up: how useful this is gets limited by the fact that entities doing the retargeting are not required to use it π)
- A stronger security solution for SIP. A bonus side effect is that each proxy that captures the "request history" information in a secure way gives the original requestor an extra means of being assured the request was properly retargeted, and this works without needing signed keys πβ¨
2. "Request History" Requirements β¨
Okay so here's the wishlist for the "Request History" capability, bestie π Every single one of these is a requirement:
- CAPABILITY-req: The "Request History" capability lets proxies and UAs that are handling a request find out its history and progress π¦ This is already built in when a retarget happens because of a SIP redirect, but it's still super useful for non-redirect retargeting too π§
- OPTIONALITY-req: The "Request History" information is optional π
- In lots of cases, whether the history gets added to the Request will just be a local policy call made by the specific application, so no special protocol element is needed.
- Since the capability is "optional" from the SIP protocol point of view, the impact on an application that doesn't have "Request History" must be described. Applicability guidelines for applications using this capability must be provided as part of the solution to these requirements.
- GENERATION-req: "Request History" information gets generated when the request is retargeted πΈ
- Sometimes more than one retarget could happen inside the same Proxy. A proxy should also generate Request History information for the 'internal retargeting'.
- An entity (UA or proxy) retargeting in response to a redirect or REFER should include any Request History information from the redirect/REFER in the new request.
- ISSUER-req: "Request History" information can be generated by a UA or proxy. It can be passed in both requests and responses π
- CONTENT-req: The "Request History" information for each occurrence of retargeting shall include the following:
- The new URI or address that the request is in the process of being retargeted to,
- The URI or address that the request was retargeted from,
- The reason for the Request-URI or address modification,
- Chronological ordering of the Request History information.
- REQUEST-VALIDITY-req: Request History applies to requests that aren't sent within an established dialog (e.g., INVITE, REGISTER, MESSAGE, and OPTIONS) π
- BACKWARDS-req: Request History information may be passed from the generating entity backwards towards the UAC. This is needed so services can tell the calling party about the dialog establishment attempts π
- FORWARDS-req: Request History information may also be included by the generating entity in the request if it gets forwarded onwards π¦
2.1. Security Requirements π
Okay, this one is a whole vibe. The Request History information is inserted by a network element that's retargeting a Request, so it's a slightly different problem than the basic SIP header problem and needs its own special attention π It's recognized that these security requirements can be generalized into one basic requirement: being able to secure information that gets inserted by proxies.
The potential security problems include the following:
- A rogue application could insert a bogus Request History entry, either by adding an extra entry as a result of retargeting or by entering invalid information π
- A rogue application could re-arrange the Request History information to change the nature of the end application or to mislead the receiver of the information π
- A rogue application could delete some or all of the Request History information π
So a security solution for "Request History" has to meet the following requirements:
- SEC-req-1: The entity receiving the Request History must be able to determine whether any of the previously added Request History content has been altered π₯
- SEC-req-2: The ordering of the Request History information must be preserved at each instance of retargeting π
- SEC-req-3: The entity receiving the information conveyed by the Request History must be able to authenticate the entity providing the request π«Ά
- SEC-req-4: To ensure the confidentiality of the Request History information, only entities that process the request should have visibility to the information π€«
It should be noted that these security requirements apply to any entity making use of the Request History information, whether it's retargeting and capturing the information, or it's an application using the information it received in either a Request or a Response π
2.2. Privacy Requirements π
Since the captured Request-URI could accidentally reveal information about the originator, there are general privacy requirements that MUST be met, and they're not optional, bestie π€
- PRIV-req-1: The entity retargeting the Request must make sure it keeps the network-provided privacy (as described in [RFC3323]) that's associated with the Request as it gets retargeted β¨
- PRIV-req-2: The entity receiving the Request History must maintain the privacy associated with the information π«’
On top of that, local policy at a proxy may identify privacy requirements associated with the Request-URI being captured in the Request History information.
- PRIV-req-3: Request History information that's subject to privacy requirements shall not be included in outgoing messages unless it's protected as described in [RFC3323] π
3. Request History Information Description π
The core job of the request history information is to let proxies and UAs involved in processing a request know about the history or progress of that request (CAPABILITY-req). The solution is to capture the Request-URIs as a request gets forwarded, in a new header for SIP messages called History-Info (CONTENT-req). This means the history of a request can be kept, even though normal SIP processing during later forwarding would otherwise lose it π§ This solution doesn't change anything about how request targets are fundamentally determined or how requests get forwarded, as defined in Sections 16.5 and 16.6 of the SIP protocol specification [RFC3261].
The History-Info header can show up in any request that isn't associated with an established dialog (e.g., INVITE, REGISTER, MESSAGE, REFER and OPTIONS, PUBLISH and SUBSCRIBE, etc.) (REQUEST-VALIDITY-req), and in any valid response to these requests (ISSUER-req) π
The History-Info header gets added to a Request when a new request is created by a UAC or forwarded by a Proxy, or when the target of a request changes. The term 'retarget' is introduced to refer to this changing of a request's target and the forwarding of that request afterwards. Worth noting: retargeting only happens when the Request-URI indicates a domain that the processing entity is responsible for π In SIP terms, the processing for retargeting is described in Sections 16.5 and 16.6 of [RFC3261]. As Section 16.5 of [RFC3261] describes, the same proxy can change the target of a request multiple times (called 'internal retargeting' in Section 2), since the proxy MAY add targets to the target set after it begins Request Forwarding. Section 16.6 of [RFC3261] describes Request Forwarding itself. The History Information gets captured during this Request Forwarding process as an optional, additional header field, so adding the History-Info header doesn't affect fundamental SIP Request Forwarding at all β¨ An entity (UA or proxy) that changes the target of a request in response to a redirect or REFER SHOULD also propagate any History-Info header from the initial Request into the new request (GENERATION-req, FORWARDS-req) π¦
3.1. Optionality of History-Info πΈ
The History-Info header is optional, which means neither UAs nor Proxies are required to support it. A new Supported header, histinfo, is included in the Request to indicate whether the History-Info header is returned in Responses (BACKWARDS-req) π On top of the histinfo Supported header, local policy decides whether the header gets added to any request, or to a specific Request-URI, being retargeted. This could limit where services that use Request History Information can work. They might be restricted to retargeting within domain(s) controlled by the same local policy, or between domain(s) that negotiate policies with other domains to make sure the given policy is supported, or to services that don't need complete History Information to provide the service (OPTIONALITY-req). All applications making use of the History-Info header MUST clearly define the impact of the information not being available, and specify the processing of such a request π
3.2. Securing History-Info π
This document defines a new header for SIP. Using the Transport Layer Security (TLS) protocol [RFC2246] as a mandatory mechanism to keep the History-Info headers confidential (SEC-req-4) is strongly RECOMMENDED π«Ά This gives History-Info at least the same level of security as other SIP headers that intermediaries insert. If TLS isn't available for the connection the request is being forwarded over, then the request MUST NOT include the History-Info header, or the request MUST be redirected to the client, including the History-Info header, so the client can retarget the request.
With the level of security TLS provides (SEC-req-3), the information in the History-Info header can be checked for removed entries by looking at the indices for gaps (SEC-req-1, SEC-req-2) π΅οΈ It's up to the application to decide whether it can use the information when entries are missing.
Note that while using the SIPS scheme protects History-Info from tampering by arbitrary parties outside the SIP message path, all the intermediaries on the path are trusted implicitly. A malicious intermediary could arbitrarily delete, rewrite, or modify History-Info. This specification doesn't try to prevent or detect attacks by malicious intermediaries. That part's on the trust chain, bestie π
3.3. Ensuring the Privacy of History-Info
okay so the History-Info header can accidentally spill info about the requestor, which [RFC3323] talks about π¬π. That's why the Privacy header SHOULD be used to decide whether an intermediary can add History-Info to a Request it receives and forwards (PRIV-req-2) or retargets (PRIV-req-1). bestie, that means History-Info SHOULD NOT be included in Requests where the requestor has indicated a priv-value of Session- or Header-level privacy π
and wait, there's more! History-Info can also reveal general routing info, and a specific intermediary or network might decide that info is private. So local policy MAY be used to decide whether to include History-Info at all, whether to capture a specific Request-URI in the header, or whether it should only be included in the Request as it gets retargeted inside a specific domain (PRIV-req-3). For that last option, a new priv-value, history, gets added to the Privacy header [RFC3323] to say whether any or a specific History-Info header(s) SHOULD be forwarded π§
It's also important to know that keeping things private can affect how well this solution works, since it can override the request that generates the info. Just like the optionality and security requirements, applications using History-Info SHOULD deal with any impact this has, or MUST explain why it doesn't impact the application π β¨
4. Request History Information Protocol Details π
This section is where the good stuff lives: the details and usage of the proposed new SIP protocol elements. It also talks through the security side of the solution π¦
4.1. Protocol Structure of History-Info
so History-Info is a header field defined by [RFC3261] π It's optional, and it MAY show up in any request or response that isn't tied to a dialog or that starts one. For example, History-Info MAY appear in INVITE, REGISTER, MESSAGE, REFER, OPTIONS, SUBSCRIBE, and PUBLISH, plus any valid responses, and NOTIFY requests that start a dialog πΈ
This document adds the following entry to Table 2 of [RFC3261]. It also gives entries for extension methods as of the time of publication. This is just a courtesy for the reader and isn't normative in any way, so don't stress about it π«Ά
Header field where proxy ACK BYE CAN INV OPT REG MSG
------------ ----- ----- --- --- --- --- --- --- ---
History-Info amdr - - - o o o o
SUB NOT REF INF UPD PRA PUB
--- --- --- --- --- --- ---
History-Info amdr o o o - - - o
The History-Info header carries the following info, and the mandatory parameters are required whenever the header is included in a request or response π
- Targeted-to-URI (
hi-targeted-to-uri): a mandatory parameter that captures the Request-URI for the specific Request as it's forwarded. - Index (
hi-index): a mandatory parameter that shows the chronological order of the info, indexed so it also reflects the forking and nesting of requests. The format is a string of digits separated by dots to show the number of forward hops and retargets. This makes a tree representation of the request's history, where the lowest-level index reflects a branch of the tree. By adding the new entries in order (following existing entries per the details in Section 4.3.3.1), including the index, and securing the header, the ordering of the History-Info headers in the request is assured (SEC-req-2). Applications can also pull out a bunch of metrics (total number of retargets, total number of retargets from a specific branch, and so on) from the index values π - Reason: an optional parameter, shown in the History-Info header by including the Reason Header [RFC3326] escaped in the
hi-targeted-to-uri. A reason is NOT included for ahi-targeted-to-uriwhen it's first added in a History-Info header. It's added when the retargeting actually happens. Yes, this does seem to complicate the security problem, but retargeting only happens when thehi-targeted-to-uripoints to a domain the processing entity is responsible for. So it's the same processing entity that first added thehi-targeted-to-URIto the header that would be updating it with the Reason π₯
Careful here: the Reason only gets added at retargeting, and only by the entity that is responsible for that domain. Don't skip that part!
- Privacy: an optional parameter, shown in the History-Info header field values by including the Privacy Header [RFC3323] with a priv-value of
"history"escaped in thehi-targeted-to-uri, or by adding the Privacy header with a priv-value of"history"to the Request. A priv-value of"history"says whether a specific History-Info header or all of them should not be forwarded π - Extension (
hi-extension): an optional parameter that allows for future optional extensions. As per [RFC3261], any implementation that doesn't understand an extension should ignore it π
Here's the syntax of the History-Info header, based on the standard SIP syntax [RFC3261] π
History-Info = "History-Info" HCOLON
hi-entry *(COMMA hi-entry)
hi-entry = hi-targeted-to-uri *( SEMI hi-param )
hi-targeted-to-uri= name-addr
hi-param = hi-index / hi-extension
hi-index = "index" EQUAL 1*DIGIT *(DOT 1*DIGIT)
hi-extension = generic-param
4.2. Protocol Examples
Here are some examples of the History-Info header! Quick heads up: the backslash and CRLF between the fields are only there for readability π
History-Info:<sip:UserA@ims.example.com?Reason=SIP%3B\
cause%3D302>;index=1;foo=bar
History-Info: <sip:UserA@ims.example.com?Reason=SIP%3B \
cause%3D302>; index=1.1,
<sip:UserB@example.com?Privacy=history&Reason=SIP%3B\
cause%3D486>;index=1.2,
<sip:45432@vm.example.com>;index=1.3
4.3. Protocol Usage
This section covers the processing for UAs and Proxies when it comes to the History-Info header, the "histinfo" option tag, and the priv-value of "history" β¨ Remember from Section 1.3 that the big goal is to capture the target Request-URIs as a request gets forwarded. That way you don't lose the history of a request to later (re)targeting and forwarding π¦ To get the full history, either the UAC must capture the Request-URI in a History-Info header in the initial request, or a proxy must add a History-Info header with both a hi-entry for the Request-URI in the initial request and a hi-entry for the target Request-URI as the request is forwarded. The basic move is for every entity forwarding a request to add a hi-entry for the target Request-URI, updating the index, and adding the Reason where it fits for any retargeted Request-URI π
4.3.1. User Agent Client (UAC) Behavior
The UAC SHOULD include the "histinfo" option tag in the Supported header in any request that isn't tied to an established dialog, if the UAC wants the History-Info header in the response π The UAC MAY also make its request more diagnosable by adding a History-Info header, using the Request-URI of the request as the hi-target-to-uri and setting the index to the RECOMMENDED value of 1 in the hi-entry. That way, intermediaries and the UAS will know at least the original Request-URI, and whether the Request-URI was changed by a previous hop π΅οΈββοΈ
Now, if the request gets routed to a redirect server and the UAC gets a 3xx response with a Contact header, the UAC MAY keep the previous hi-entry(s) in the request. In that case, the reason header SHOULD be associated with the hi-targeted-to-uri in the previous (last) hi-entry, as described in Section 4.3.3.1.2. A new hi-entry MAY then be added for the URI from the Contact header, which becomes the new Request-URI. Here the index is created by reading and incrementing the value of the index from the previous hi-entry, so it follows the same rules as a proxy does when retargeting, described in Section 4.3.3.1.3. You can see an example of this in Appendix D π§
If a UAC doesn't want History-Info added for privacy reasons, it SHOULD include a Privacy header with a priv-value(s) of "session", "header", or "history" in the request π
Apart from the 3xx processing above, how the History-Info header in the Response gets processed is application specific and outside the scope of this document. Still, the validity of the info SHOULD be ensured before any application uses it. For example, the entries MAY be checked for gaps in indices, since a gap could mean an entry was maliciously removed or removed for privacy reasons. Either way, an application MAY want to know about potentially missing info π«£
4.3.2. User Agent Server (UAS) Behavior
How a UAS processes the History-Info header in a Request depends on local policy and on the specific applications at the UAS that might use the info πΈ Before any application uses the info, its validity SHOULD be ascertained. For example, the entries MAY be checked for gaps in indices, which could mean an entry was maliciously removed or removed for privacy reasons. Either way, an application MAY want to be aware of potentially missing info.
If the "histinfo" option tag shows up in a request, the UAS SHOULD include any History-Info it received in the request in the response that follows π
4.3.3. Proxy Behavior π¦
okay so proxies are the middle-people of SIP, and putting the History-Info header in a Request doesn't change how they figure out request targets. That's still all Section 16.5 of [RFC3261] π . Whether a proxy adds the History-Info header or a new hi-entry as it forwards a Request depends on a few things:
- Whether the Request contains the
histinfooption tag in theSupportedheader. π - Whether the proxy supports the History-Info header. π€
- Whether the Request contains a
Privacyheader with apriv-valueofsession,header, orhistory. π - Whether any History-Info header added for a proxy/domain should go outside that domain. This one is so real. The header can be super useful inside the domain where the request got retargeted, but policies (for privacy, user and network security, etc.) would prohibit that info from being exposed outside that domain. So a proxy MAY insert the
Privacyheader with apriv-valueofhistorywhen the request is being forwarded within the same domain. There's an example of this in Appendix C π§ - Whether a hi-entry is added for a specific Request-URI because of local privacy policy. A proxy MAY add the
Privacyheader with apriv-valueofhistoryassociated with the specific hi-targeted-to-uri. π
An example policy would be a proxy that only adds the History-Info header if the histinfo option tag is in the Supported header. πΈ Other proxies might always add the header but never forward it outside a particular domain. They do this by adding a Privacy header with a priv-value of history to each hi-entry, so the info can only be collected for internal retargeting. Very secret-agent of them π΅οΈββοΈ
Each application that uses the History-Info header SHOULD address the impacts of local policies on that specific application. Like, figure out what local policy is actually needed for that application, and what limits local policy decisions might put on it. β¨
Consistent with basic SIP processing of optional headers, proxies SHOULD maintain the History-Info header(s) they received in messages being forwarded, whether or not local policy supports History-Info. Keep those headers, bestie π«Ά
The specific steps proxies take to add History-Info headers in Requests and Responses, with all the considerations above in mind, are explained in detail in the following sections. π
4.3.3.1. Adding the History-Info Header to Requests
okay this is where it gets juicy π₯ After checking the considerations for when the History-Info header should be included in requests (no Privacy header overriding inclusion, local policy supports it, etc.), which are covered in Section 4.3.3, a proxy SHOULD add a hi-entry as it forwards a Request. Section 16.6 of [RFC3261] lists the steps a proxy follows when forwarding a Request. Step 5 is where optional headers get added. That sounds like the perfect spot for History-Info, but Step 6, "Postprocess routing information", plus a strict route in the Route header could change the Request-URI. So adding the History-Info header between Steps 8 (adding Via header) and 9 (adding Content-Length) is RECOMMENDED. π
Also, with loose routing, the Request-URI doesn't change while a Request is forwarded. So capturing History-Info for that kind of request would give you duplicate Request-URIs with different indices. Not cute π
The hi-entry MUST be added after any hi-entry received in the request being forwarded. And if a request shows up without a History-Info header, the proxy MAY add a History-Info header with a hi-entry that goes before the one for the current request being forwarded. The index for that hi-entry is RECOMMENDED to start at 1. π The subsections below spell out exactly how to create the info for each hi-entry.
4.3.3.1.1. Privacy in the History-Info Header
If there's a Privacy header in the request with a priv-value of session, header, or history, a hi-entry MAY be added, as long as the request is going to a Request-URI tied to a domain the processing entity is responsible for (and local policy supports the History-Info header, etc.). π
But if the request is going to a Request-URI tied to a domain the proxy is NOT responsible for, and there's a Privacy header with a priv-value of session, header, or history, the proxy SHOULD remove any hi-entry(s) before forwarding. That depends on local policy, and on whether the proxy might know ahead of time that it can count on a downstream privacy service to apply the requested privacy. Tricky, but you've got this π
Now for when there's no Privacy header in the request and it's going to a Request-URI tied to domain(s) this entity is responsible for. There are a few extra things to think about:
- If there's no local policy about privacy, then a hi-entry MAY be added to the Request. π
- If the proxy's local policies, per consideration 4 in Section 4.3.3, say the History-Info header shouldn't be forwarded beyond the domain this intermediary is responsible for, then a
Privacyheader with apriv-valueofhistorySHOULD be associated with each hi-entry that proxy adds in this scenario. π - If the proxy's policy, per consideration 5 in Section 4.3.3, says History-Info for a specific Request-URI shouldn't be forwarded beyond the domain this intermediary is responsible for, then a
Privacyheader with apriv-valueofhistorySHOULD be associated with that specific hi-entry, for that specific hi-targeted-to-uri, added by that proxy in this scenario. π
If a request is going to a Request-URI tied to a domain the proxy is NOT responsible for, and local policy requires privacy for any hi-entries it added (or specific ones), any hi-entry with a priv-value of history SHOULD be removed before forwarding. π
4.3.3.1.2. Reason in the History-Info Header
For retargets that happen because of an explicit SIP response, a Reason MUST be associated with the hi-targeted-to-uri. If the SIP response doesn't include a Reason header, the SIP Response Code that triggered the retargeting MUST be included as the Reason for the hi-targeted-to-uri that got retargeted. π If the response has a non-SIP Reason header (like Q.850), it MUST be captured as an additional Reason for the retargeted hi-targeted-to-uri, along with the SIP Response Code. And if the Reason header is a SIP reason, it MUST be used as the Reason for the hi-targeted-to-uri instead of the SIP response code. Priority check β¨
For retargets caused by timeouts or internal events, a Reason MAY be associated with the retargeted hi-targeted-to-uri. πΈ
The Reason should be added before the request is forwarded (forwarding might add a new hi-entry with a new hi-targeted-to-uri). It goes with the hi-targeted-to-uri that got retargeted, because it explains why the Request to that specific URI didn't work out. π₯²
4.3.3.1.3. Indexing in the History-Info Header
To keep everything in order and accurately show how the request was nested and retargeted, an index MUST be included along with each Targeted-to-URI that gets captured. According to the syntax in Section 4.1, the index is a dot-delimited series of digits, like 1.1.2. Each dot is a hop or level of nesting, so the number of hops is the total number of dots. Within each level, the integer shows how many peer entities the request was routed to. So the indexing builds a logical tree of the Request's history. π³ It's RECOMMENDED that each level of indexing starts at 1, and that an increment of 1 is used when moving to a new branch.
Here are the basic rules for adding the index, in a nutshell:
- Basic Forwarding: When a Request is being forwarded, the index gets another level added, because the branch is getting deeper. The proxy reads the value from the History-Info header in the received request (if there is one), then adds another level by appending a dot and a starting index for the new level, which is RECOMMENDED to be 1. For example, if the index in the last History-Info header field of the received request is
1.1, this proxy sets its index to1.1.1and forwards the request. π - Retargeting within a Proxy - 1st instance: For the first time a proxy retargets, the index is calculated the same way as for basic forwarding. β¨
- Retargeting within a Proxy - subsequent instance: Each later retarget by the same proxy adds another branch. The index for each new branch is calculated by incrementing the last/lowest digit at the current level. Following the example above, the index in the next request forwarded by this same proxy would be
1.1.2. π - Retargeting based upon a Response: When retargeting happens because of a specific response (like 302), the index is calculated using rule 3. So the lowest/last digit of the index gets incremented (a new branch is created), with the increment RECOMMENDED to be 1. For example, if the index in the History-Info header of the received request was
1.2, then the index in the History-Info header field for the new hi-targeted-to-URI would be1.3. π¦ - Retargeting the request in parallel (forking): If the request is forwarded in parallel, the index MUST be captured for each forked request using the rules above, and each new Request has a unique index. The only difference in messaging compared to basic proxy retargeting in rules 2 and 3 is that these forwarded requests don't have History-Info entries associated with their peers. The proxy builds the response (or request) afterward using the aggregated info from each of those requests, and includes the header entries in the order the indexing shows. Responses are processed as described in Section 16.7 of [RFC3261], with the aggregated History-Info entries handled similarly to Step 7, "Aggregate Authentication Header Field Values". Section 4.5 has an example of a parallel request scenario that shows off this indexing mechanism. π
4.3.3.2. Processing History-Info in Responses β¨
okay bestie, so when a proxy gets a Request with the "histinfo" option tag in its Supported header, it SHOULD send back the History-Info it captured in later responses, both provisional and final π (this depends on local policy supporting History-Info capture). but there are privacy rules you have to follow ππ«Ά
- if the response is heading to a Request-URI for a domain the proxy isn't responsible for, AND the request the proxy got had a Privacy header with a priv-value of "session", "header", or "history", the proxy MUST remove the History-Info header (meaning all the hi-entries) before forwarding π
- if a request is going to a Request-URI on a domain the proxy isn't responsible for, AND local policy says privacy applies to any or all of the hi-entries it added, then any hi-entry with a priv-value of "history" MUST be removed before forwarding πΈ
- if a proxy gets a response from another intermediary for a domain it IS responsible for, and that response has hi-entries with privacy headers, and the response is going to a domain it is NOT responsible for, then those hi-entries MUST be removed π
processing History-Info in responses follows the same method as Section 16.7 of [RFC3261], it just adds one extra step right before Step 9, "Forwarding the Response" β¨π¦
4.3.4. Redirect Server Behavior π§
a redirect server SHOULD NOT add any new History-Info, because that's the job of whoever receives the 3xx response π ββοΈ but it MAY include History-Info in responses by copying any History-Info headers it got in a request into a later response π
4.4. Security for History-Info π
as we talked about in Section 3, the security stuff relies on TLS (a basic SIP requirement per [RFC3261]) for hop-by-hop security, so that's the recommendation π if TLS isn't available on the connection a request with a History-Info header is being forwarded over, then one of these two options MUST be implemented:
- the History-Info header MUST be removed before forwarding the request, or
- the request MUST be redirected, with the History-Info header included in the response, so the UAC can securely send the request again with the History-Info header π«Ά
4.5. Example Applications Using History-Info π
okay this scenario shows an example where the History-Info in the response is mainly useful for not retrying routes that another proxy already tried π¦ just know this is only an example, because there can be totally valid reasons a Proxy would want to retry routes, so that would probably be a local proxy or even user-specific policy π
UA1 sends a call to Bob to proxy 1. Proxy 1 forwards the request to Proxy 2. Proxy 2 sends the requests in parallel and tries several places (UA2, UA3, and UA4) before sending a response to Proxy 1 that all the places are busy. Proxy 1, without the History-Info, would try some of the same places (e.g., UA3) based upon registered contacts for Bob, before completing at UA5. However, with the History-Info, Proxy 1 determines that UA3 has already received the invite; thus, the INVITE goes directly to UA5. β¨
Section 4.5.1 provides this same scenario using one of the privacy mechanisms, with Proxy2 (P2) adding the Privacy header indicating that the History-Info header is not to be propagated outside P2's domain. This scenario highlights the potential functionality lost with the use of "history" privacy in the Privacy header for the entire request and the need for careful consideration on the use of privacy for History-Info. π
Section 4.5.2 also provides the same scenario using one of the privacy mechanisms, however, due to local policy at Proxy2, only one of the Request-URIs (UA4) in the History-Info contains a priv-value of "history", thus allowing some optimized functionality in the routing of the request, but still maintaining privacy for specific URIs. π
the formatting in these scenarios is just for visual purposes π so backslash and CRLF are used between the fields for readability, and the headers in the URI are not shown properly formatted for escaping. Refer to Section 4.2 examples for the proper formatting. Additional detailed scenarios are available in the appendix. π§
UA1 Proxy1 Proxy2 UA2 UA3 UA4 UA5
| | | | | | |
|--INVITE -->| | | | | |
| |-INVITE->| | | | |
Supported: histinfo
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1
| | | | | | |
| | |-INVITE>| | | |
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1,
<sip:User2@UA2.example.com>;index=1.1.1
| | | | | | |
| | |-----INVITE ---->| | |
History-Info:<sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User3@UA3.example.com>;index=1.1.2
| | | | | | |
| | |-------INVITE------------>| |
History-Info:<sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1,
<sip:User4@UA4.example.com>;index=1.1.3
/* All Responses from the INVITEs indicate non-success/non-
availability*/
| | | | | | |
| |<-480 ---| | | | |
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User2@UA2.example.com?Reason=SIP;\
cause=408;text="RequestTimeout">;index=1.1.1,
<sip:User3@UA3.example.com?Reason=SIP; \
cause=487;text="Request Terminated">; index=1.1.2,
<sip:User4@UA4.example.com?Reason=SIP;\
cause=603;text="Decline">; index=1.1.3
| | | | | | |
/* Upon receipt of the response, P1 determines another route for the
INVITE, but finds that it matches a route already attempted
(e.g., UA3), thus the INVITE is only forwarded to UA5, where
the session is successfully established */
| | | | | | |
| |----------------INVITE --------------------->|
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User2@UA2.example.com?Reason=SIP;cause=408;\
text="RequestTimeout">;index=1.1.1,
<sip:User3@UA3.example.com?Reason=SIP;cause=487;\
text="Request Terminated">; index=1.1.2,
<sip:User4@UA4.example.com?Reason=SIP;cause=603;\
text="Decline">; index=1.1.3
<sip:User5@UA5.example.com>;index=1.2
| | | | | | |
| |<-----200 OK---------------------------------|
|<--200 OK---| | | | | |
| | | | | | |
|--ACK --------------------------------------------------->|
4.5.1. Example with Privacy Header for Entire Request at Proxy2 π
UA1 Proxy1 Proxy2 UA2 UA3 UA4 UA5
| | | | | | |
|--INVITE -->| | | | | |
| |-INVITE->| | | | |
Supported: histinfo
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1
| | | | | | |
| | |-INVITE>| | | |
Privacy: history
History-Info:<sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1,
<sip:User2@UA2.example.com>;index=1.1.1
| | | | | | |
| | |-----INVITE ---->| | |
Privacy: history
History-Info:<sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User3@UA3.example.com>;index=1.1.2
| | | | | | |
| | |-------INVITE------------>| |
Privacy: history
History-Info:<sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1,
<sip:User4@UA4.example.com>;index=1.1.3
/* All Responses from the INVITEs indicate non-success/non-
availability and only the initial, received History-Info entries
are NOT returned to P1 due to the Privacy header value.*/
| | | | | | |
| |<-480 ---| | | | |
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1
| | | | | | |
/* Upon receipt of the response, P1 determines another route for the
INVITE, including UA3, which was attempted by P2, but due to
Privacy P1 is not aware of this, so UA3 is re-attempted prior to
forwarding the INVITE to UA5, where the session is successfully
established */
| | | | | | |
| |--------------INVITE ----->| | |
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User3@UA3.example.com>; index=1.2
| | | | | | |
| |<-- 486 -------------------| | |
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User3@UA3.example.com>; index=1.2
| | | | | | |
| |----------------INVITE --------------------->|
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User3@UA3.example.com?Reason=SIP;cause=486;\
text="Busy Here">;index=1.2,
<sip:User5@UA5.example.com>;index=1.3
| | | | | | |
| |<-----200 OK---------------------------------|
|<--200 OK---| | | | | |
| | | | | | |
|--ACK --------------------------------------------------->|
4.5.2. Example with Privacy Header for Specific URI (UA4) at Proxy2 π§
okay so this is the sequel to the last example and it's giving privacy drama ππ UA4 asks for privacy on just its own URI, so the History-Info entry for UA4 gets left out of the responses. Everyone else's history stays visible. Here's the whole flow:
UA1 Proxy1 Proxy2 UA2 UA3 UA4 UA5
| | | | | | |
|--INVITE -->| | | | | |
| |-INVITE->| | | | |
Supported: histinfo
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1
| | | | | | |
| | |-INVITE>| | | |
History-Info:<sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1,
<sip:User2@UA2.example.com>;index=1.1.1
| | | | | | |
| | |-----INVITE ---->| | |
History-Info:<sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1,
<sip:User3@UA3.example.com>;index=1.1.2
| | | | | | |
| | |-------INVITE------------>| |
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>;index=1.1,
<sip:User4@UA4.example.com?\
Privacy=history>; index=1.1.3
/* All Responses from the INVITEs indicate non-success/non-
availability. The History-Info associated with UA4 is not returned
in the response due to the privacy header associated with that URI */
| | | | | | |
| |<-480 ---| | | | |
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User2@UA2.example.com?Reason=SIP;\
cause=408;text="RequestTimeout">;index=1.1.1,
<sip:User3@UA3.example.com?Reason=SIP; \
cause=487;text="Request Terminated">; index=1.1.2,
| | | | | | |
/* Upon receipt of the response, P1 determines another route for the
INVITE, but finds that it matches a route already attempted
(e.g., UA3), thus the INVITE is only forwarded to UA5, where
the session is successfully established */
| | | | | | |
| |----------------INVITE --------------------->|
History-Info: <sip:Bob@P1.example.com>;index=1,
<sip:Bob@P2.example.com>; index=1.1,
<sip:User2@UA2.example.com?Reason=SIP;cause=408;\
text="RequestTimeout">;index=1.1.1,
<sip:User3@UA3.example.com?Reason=SIP;cause=487;\
text="Request Terminated">; index=1.1.2,
<sip:User5@UA5.example.com>;index=1.2
| | | | | | |
| |<-----200 OK---------------------------------|
|<--200 OK---| | | | | |
| | | | | | |
|--ACK --------------------------------------------------->|
Quick vibe check: UA2 and UA3 both bail (408 and 487), so P1 tries a new route. It bumps into UA3 again, which already got tried, so it skips that and goes straight to UA5, and the call finally lands β¨π. And through all of it, UA4's entry is nowhere to be seen in the responses because of that privacy request ππ
5. Application Considerations πΈ
okay so the appendix examples show just how flexible History-Info is π¦ Intermediaries and UAs can build all kinds of services on top of it. But if you're building a service that uses History-Info, you need to keep these things in mind:
- History-Info is optional, so a service MUST define default behavior for requests and responses that don't contain History-Info headers. π
- History-Info can be affected by privacy. If a UA asks for Header-, Session-, or History-level privacy (or an intermediary imposes it), History-Info might not show up in a request or response. Apps that need it should handle that the same way as point 1, with reasonable default behavior for when the info is missing. π«Ά
- History-Info can also be affected by local policy. Every application that uses the History-Info header SHOULD think about how local policies affect it, like what local policy specification the app really needs and what limits local policy decisions might put on it. This is related to the optionality and privacy points above, but it goes further. For example, because of optionality and privacy, an entity might only get partial History-Info entries. Will that be enough? π€ That could be a real limitation for debugging, but it might be totally fine for models where only one specific intermediary's info matters. π
- The security of the History-Info header requires the use of TLS. If TLS isn't available on a connection a request is being forwarded over, the History-Info header may be removed from that request. How bad it is to lack the info depends on the app. Is it something that shows up on a screen, or is it processed by automata where missing info could mess up how the request gets handled later? π¬ It's suggested that the app evaluates the impact of an intermediary that doesn't support the security recommendations, so it can make sure everything is covered. π
6. Security Considerations π
okay this section is serious business, bestie π The threat model and the related security and privacy requirements for the History-Info header are described in Sections 2.1 and 2.2 of this document. Sections 3.2, 3.3, and 4.4 give the normative recommendations that meet those requirements. TLS is mandated between every entity that uses the History-Info header: UAC to Proxy, Proxy to Proxy, and Proxy to UAS. If TLS isn't available for a specific connection, Section 5 explains how to handle the request.
With TLS, History-Info headers are no less secure, and no more secure, than other SIP headers. Honestly, other SIP headers usually have a bigger impact on how SIP sessions get processed afterward than History-Info does π β¨
7. IANA Considerations π
7.1. Registration of New SIP History-Info Header π¦
This document defines a brand-new SIP header field name, History-Info, and a new option tag, histinfo. β¨
The following changes have been made to http:///www.iana.org/assignments/sip-parameters.
The following row has been added to the header field section:
Header Name Compact Form Reference
----------- ------------ ---------
History-Info none [RFC4244]
The following has been added to the Options Tags section:
Name Description Reference
---- ----------- ---------
histinfo When used with the Supported header, [RFC4244]
this option tag indicates support
for the History Information to be
captured for requests and returned in
subsequent responses. This tag is not
used in a Proxy-Require or Require
header field since support of
History-Info is optional.
7.2. Registration of "history" for SIP Privacy Header π
This document defines a new priv-value for the SIP Privacy header, which is history. π
The following changes have been made to http://www.iana.org/assignments/sip-priv-values.
The following has been added to the registration for the SIP Privacy header:
Name Description Registrant Reference
---- ----------- ---------- ---------
history Privacy requested for Mary Barnes [RFC4244]
History-Info header(s) mary.barnes@nortel.com
8. Normative References π
- [RFC3261] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, June 2002.
- [RFC3326] Schulzrinne, H., Oran, D., and G. Camarillo, "The Reason Header Field for the Session Initiation Protocol (SIP)", RFC 3326, December 2002.
- [RFC3323] Peterson, J., "A Privacy Mechanism for the Session Initiation Protocol (SIP)", RFC 3323, November 2002.
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC 2246, January 1999.
9. Informative References π
- [RFC3665] Johnston, A., Donovan, S., Sparks, R., Cunningham, C., and K. Summers, "Session Initiation Protocol (SIP) Basic Call Flow Examples", BCP 75, RFC 3665, December 2003.
10. Acknowledgements π«Ά
The editor wants to give a huge thank-you to Robert Sparks, Paul Kyzivat, Scott Orton, John Elwell, Nir Chen, Francois Audet, Palash Jain, Brian Stucker, Norma Ng, Anthony Brown, Jayshree Bharatia, Jonathan Rosenberg, Eric Burger, Martin Dolly, Roland Jesske, Takuya Sawada, Sebastien Prouvost, and Sebastien Garcin for their constructive feedback. π
The editor also wants to shout out Rohan Mahy for significant input on some of the normative parts of the ABNF, especially the need for and format of the index, and on the security parts. π
11. Contributors' Addresses π
Cullen, Mark, and Jon contributed to the development of the initial requirements. Cullen and Mark gave a lot of input through email discussion while the initial version of the individual solution document was being written. πΈ
Cullen Jennings
Cisco Systems
170 West Tasman Dr
MS: SJC-21/3
Phone: +1 408 421 9990
EMail: fluffy@cisco.com
Jon Peterson
NeuStar, Inc.
1800 Sutter Street, Suite 570
Concord, CA 94520
USA
Phone: +1 925-363-8720
EMail: Jon.Peterson@NeuStar.biz
Mark Watson
Digital Fountain
39141 Civic Center Drive Suite 300
Fremont, CA 94538
U.S.A.
EMail: mark@digitalfountain.com
Appendix. Example Scenarios π§β¨
okay so the scenarios in Appendices A-D are sample use cases for the History-Info header, and they're for informational purposes only π They aren't normative, and the formatting is just for visual purposes, so the headers in the URIs aren't shown properly escaped. For the correctly formatted versions, check out the examples in Section 4.2 π¦
Appendix A. Sequentially Forking (History-Info in Response) π¦
okay so this scenario is so good for showing why History-Info in the response is useful to whoever started the request π It's the originator who gets to see what happened, not just a dead-end "nope" π«Ά
Alice at UA1 calls Bob through Proxy1. Proxy1 goes down the list and tries UA2, then UA3, then UA4. None of them work out, so Proxy1 sends a response back to Alice π
The whole point is that once UA1 has the History-Info, the end-user or an app at UA1 can decide how to try reaching Bob next π§ Without it, UA1 might try UA3 (and therefore UA4) and then end up retrying UA4 on a third manual attempt, which is so much effort for nothing π With it, the user or the app can see that Bob is busy on his home phone and is physically not in the office π’ If there's another address for Bob that nobody has tried yet, the app or the user can go try that one πΈ This is the flexibility part: the mechanism can power applications well beyond SIP, and this document is not the place to prescribe detailed applications β¨
Quick detail: UA1 didn't include the original Request-URI in the INVITE, so the proxy adds a hi-entry to capture it, so you get the complete picture. See Section 4.3.3.1 for more on that π
UA1 Proxy1 UA2 UA3 UA4
| | | | |
|-INVITE F1->| | | |
| | | | |
| |--INVITE F2------>| | |
|<--100 F3---| | | |
| |<-302 F4----------| | |
| | | | |
| |-------INVITE F5 --------->| |
| | | | |
| |<-------180 F6 ------------| |
|<---180 F7--| | | |
| . . |---retransmit INVITE ----->| |
| | | | |
| | ( timeout ) | | |
| | | | |
| |------INVITE F8 ------------------->|
|<--100 F9 --| | | |
| | | | |
| |<-486 F10 --------------------------|
| | | | |
| |-- ACK F11------------------------->|
|<--486 F12--| | | |
| | | | |
|--ACK F13-->| | | |
| | | | |
Message Details π
F1 INVITE UA1 ->Proxy1
INVITE sip:UserA@example.com SIP/2.0
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Contact: Alice <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=UserA 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
/*Client for UA1 prepares to receive data on port 49170
from the network. */
F2 INVITE Proxy1 ->UA2
INVITE sip:UserA@ims.example.com SIP/2.0
Via: SIP/2.0/UDP ims.example.com:5060;branch=1
Via: SIP/2.0/UDP example.net:5060
Record-Route: <sip:UserA@example.com>
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
History-Info: <sip:UserA@example.com>; index=1,
<sip:UserA@ims.example.com>; index=1.1
Contact: Alice <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=UserA 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
F3 100 Trying Proxy1 ->UA1
SIP/2.0 100 Trying
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
F4 302 Moved Temporarily UA2 ->Proxy1
SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP ims.example.com:5060;branch=1
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>;tag=3
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Contact: <sip:UserB@example.com>
Content-Length: 0
F5 INVITE Proxy1 -> UA3
INVITE sip:UserB@example.com SIP/2.0
Via: SIP/2.0/UDP ims.example.com:5060;branch=2
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
History-Info: <sip:UserA@example.com>; index=1,
<sip:UserA@ims.example.com?Reason=SIP;\
cause=302; text="Moved Temporarily">; index=1.1,
<sip:UserB@example.com>;index=1.2
CSeq: 1 INVITE
Contact: Alice <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=User1 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
F6 180 Ringing UA3 ->Proxy1
SIP/2.0 180 Ringing
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>;tag=5
Call-ID: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
F7 180 Ringing Proxy1 -> UA1
SIP/2.0 180 Ringing
SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
/* User B is not available. INVITE is sent multiple
times until it times out. */
/* The proxy forwards the INVITE to UA4 after adding the
additional History Information entry. */
F8 INVITE Proxy1 -> UA4
INVITE sip:UserC@example.com SIP/2.0
Via: SIP/2.0/UDP ims.example.com:5060;branch=3
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
History-Info: <sip:UserA@example.com>; index=1,
<sip:UserA@ims.example.com?Reason=SIP;\
cause=302; text="Moved Temporarily">;index=1.1,
<sip:UserB@example.com?Reason=SIP;cause=480;\
text="Temporarily Unavailable" >;index=1.2,
<sip:UserC@example.com>;index=1.3
CSeq: 1 INVITE
Contact: Alice <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=User1 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
F9 100 Trying Proxy1 ->UA1
SIP/2.0 100 Trying
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
F10 486 Busy Here UA4 -> Proxy1
SIP/2.0 486 Busy Here
Via: SIP/2.0/UDP ims.example.com:5060;branch=3
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
F11 ACK Proxy1 -> UA4
ACK sip:UserC@example.com SIP/2.0
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 ACK
Content-Length: 0
/* The proxy forwards the 486 to Alice after adding the
associated History Information entries from the series of
INVITES */
F12 486 Busy Here Proxy1 -> UA1
SIP/2.0 486 Busy Here
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
History-Info: <sip:UserA@example.com>; index=1,
<sip:UserA@ims.example.com?Reason=SIP;\
cause=302; text="Moved Temporarily">;index=1.1,
<sip:UserB@example.com?Reason=SIP;cause=480;\
text="Temporarily Unavailable" >;index=1.2,
<sip:UserC@example.com>;index=1.3
CSeq: 1 INVITE
Content-Length: 0
F13 ACK Alice -> Proxy 1
ACK sip:UserA@example.com SIP/2.0
Via: SIP/2.0/UDP example.net:5060
From: Alice <sip:User1@example.net>
To: Bob <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 ACK
Content-Length: 0
And that's the whole sequence, bestie! π Bob's busy, the full History-Info trail comes back to Alice, and she gets to make the call on what to do next π
Appendix B. Voicemail π
Okay so this scenario is all about how the History-Info in a request is mainly useful to an edge service, like a voicemail server ππ. Quick heads up though, bestie: this is not a full spec for that service. The voicemail server almost certainly needs more info than this, and History-Info is just one building block it uses π§±β¨.
Here's the setup. UA1 calls UA A, which forwards to UA B, which forwards to a UA VM (the voicemail server) π¬. Based on the retargeted URIs, the Reasons, and other stuff in the INVITE, the VM server makes a policy decision about which mailbox to use, which greeting to play, and so on. It's giving smart call routing π
UA1 Proxy UA-A UA-B UA-VM
| | | | |
|--INVITE F1-->| | | |
| | | | |
| |--INVITE F2-->| | |
|<--100 F3-----| | | |
| |<-302 F4------| | |
| | | | |
| |--------INVITE F5---------->| |
| | | | |
| |<--------180 F6-------------| |
|<---180 F7----| | | |
| . . . | | | |
| |------retransmit INVITE---->| |
| . . . | | | |
| | (timeout) | |
| | | | |
| |-------INVITE F8---------------------->|
| | | | |
| |<-200 F9-------------------------------|
| | | | |
|<-200 F10-----| | | |
| | | | |
|--ACK F11-------------------------------------------->|
Message Details π
INVITE F1 UA1->Proxy
INVITE sip:UserA@example.com SIP/2.0
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Contact: BigGuy <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=UserA 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
/*Client for UA1 prepares to receive data on port 49170
from the network. */
INVITE F2 Proxy->UA-A
INVITE sip:UserA@ims.example.com SIP/2.0
Via: SIP/2.0/UDPims.example.com:5060;branch=1
Via: SIP/2.0/UDP example.net:5060
Record-Route: <sip:UserA@example.com>
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
History-Info: <sip:UserA@ims.example.com>; index=1
Contact: BigGuy <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=UserA 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
100 Trying F3 Proxy->UA1
SIP/2.0 100 Trying
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
302 Moved Temporarily F4 UserA->Proxy
SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP ims.example.com:5060;branch=1
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy<sip:UserA@example.com>;tag=3
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Contact: <sip:UserB@example.com>
Content-Length: 0
INVITE F5 Proxy-> UA-B
INVITE sip:UserB@example.com SIP/2.0
Via: SIP/2.0/UDP ims.example.com:5060;branch=2
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>
Call-Id: 12345600@example.net
History-Info: <sip:UserA@ims.example.com?Reason=SIP;\
cause=302; text="Moved Temporarily">; index=1,
<sip:UserB@example.com>;index=2
CSeq: 1 INVITE
Contact: BigGuy <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=User1 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
180 Ringing F6 UA-B ->Proxy
SIP/2.0 180 Ringing
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>;tag=5
Call-ID: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
180 Ringing F7 Proxy-> UA1
SIP/2.0 180 Ringing
SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Content-Length: 0
/* User B is not available. INVITE is sent multiple
times until it times out. */
/* The proxy forwards the INVITE to UA-VM after adding the
additional History Information entry. */
INVITE F8 Proxy-> UA-VM
INVITE sip:VM@example.com SIP/2.0
Via: SIP/2.0/UDP ims.example.com:5060;branch=3
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>
Call-Id: 12345600@example.net
History-Info:<sip:UserA@ims.example.com?Reason=SIP;\
cause=302; text="Moved Temporarily">;index=1,
<sip:UserB@example.com?Reason=SIP;cause=480;\
text="Temporarily Unavailable" >;index=2,
<sip:VM@example.com>;index=3
CSeq: 1 INVITE
Contact: BigGuy <sip:User1@example.net>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=User1 2890844526 2890844526 IN IP4 client.example.net
s=Session SDP
c=IN IP4 192.0.2.3
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
200 OK F9
SIP/2.0 200 OK UA-VM->Proxy
Via: SIP/2.0/UDP ims.example.com:5060;branch=3
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>;tag=3
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Contact: TheVoiceMail <sip:VM@example.com>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=UserA 2890844527 2890844527 IN IP4 vm.example.com
s=Session SDP
c=IN IP4 192.0.2.4
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000
200 OK F10 Proxy->UA1
SIP/2.0 200 OK
Via: SIP/2.0/UDP ims.example.com:5060;branch=3
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy <sip:UserA@example.com>;tag=3
Call-Id: 12345600@example.net
CSeq: 1 INVITE
Contact: TheVoiceMail <sip:VM@example.com>
Content-Type: application/sdp
Content-Length: <appropriate value>
v=0
o=UserA 2890844527 2890844527 IN IP4 vm.example.com
s=Session SDP
c=IN IP4 192.0.2.4
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000
ACK F11 UA1-> UA-VM
ACK sip:VM@example.com SIP/2.0
Via: SIP/2.0/UDP example.net:5060
From: BigGuy <sip:User1@example.net>
To: LittleGuy<sip:UserA@example.com>;tag=3
Call-Id: 12345600@example.net
CSeq: 1 ACK
Content-Length: 0
/* RTP streams are established between UA1 and
UA-VM. UA-VM starts announcement for UA1 */
Appendix C. Automatic Call Distribution Example πΌ
Now for an Automatic Call Distribution (ACD) example, which is a really fun one ππΈ. Agents are split into groups based on the type of customer they handle. Here, Gold customers get higher priority than Silver customers. So a Gold call still gets served even if every agent in the Gold group (ACDGRP1) is busy, because the request gets retargeted to the Silver group π₯β‘οΈπ₯.
When the call lands on the agent who's handling it, the application at that agent can look at the History-Info header in the message. From that, it can tell that this is a Gold call, how many groups it might have overflowed through before reaching the agent, and so on. That means the call can be handled appropriately πβ¨
For scenarios where calls might overflow from the Silver to the Gold, the alternate group identification, internal routing, or actual agent that handles the call SHOULD not be sent to UA1. So, for this scenario, you'd expect the Proxy would not support sending the History-Info in the response, even if the calling UA asks for it π
As with the other examples, this isn't prescriptive about how you'd build this type of service. It's just an example of a subset of the processing that might go with it π§. Also, this example doesn't touch on any aspects of Agent availability, which might also be handled over a SIP interface π
UA1 Proxy ACDGRP1 Svr ACDGRP2 Svr UA2-ACDGRP2
| | | | |
|--INVITE F1-->| | | |
Supported:histinfo
| | | | |
| |--INVITE F2-->| | |
Supported:histinfo
History-Info: <sip:Gold@example.com>; index=1
History-Info: <sip:ACDGRP1@example.com>; index=1.1
| | | | |
| |<-302 F3------| | |
Contact: <sip:ACDGRP2@ACD.com>
| | | | |
| |--------INVITE F4---------->| |
History-Info: <sip:Gold@example.com>; index=1
History-Info: <sip:ACDGRP1@example.com>; index=1.1
History-Info: <sip:ACDGRP2@example.com>; index=1.2
| | | | |
| | | | |
| | | |INVITE F5>|
History-Info: <sip:Gold@example.com>; index=1
History-Info: <sip:ACDGRP1@example.com>; index=1.1
History-Info: <sip:ACDGRP2@example.com>; index=1.2
| | | | |
| | | |<-200 F6--|
| | | | |
| |<-200 F7--------------------| |
History-Info: <sip:Gold@example.com>; index=1
History-Info: <sip:ACDGRP1@example.com>; index=1.1
History-Info: <sip:ACDGRP2@example.com>; index=1.2
|<-200 F8------| | | |
< No History-Info included in the response due to Local Policy>
| | | | |
|--ACK F9--------------------------------------------->|
Appendix D. Session via Redirect and Proxy Servers β¨
Okay so this one is a journey π¦. Alice wants to call Bob, but her first stop is a Redirect server, and then she gets sent on to a Proxy Server to finally reach him. The first INVITE goes to the Redirect Server, which replies with a 302 Moved Temporarily (that's F2) carrying a Contact header with Bob's current SIP address. Alice then builds a brand new INVITE that includes Bob's current address as another History-Info entry. That INVITE goes to Bob through the Proxy Server, so Bob gets the whole History information, and the call just carries on like normal π . If you want the full call flow without History-Info, it's in Section 3.6 of the SIP Basic Call Flow Examples [RFC3665]. Iconic π
Alice Redirect Server Proxy 3 Bob
| | | |
| INVITE F1 | | |
|--------------->| | |
| 302 F2 | | |
|<---------------| | |
| ACK F3 | | |
|--------------->| | |
| INVITE F4 | |
|-------------------------------->| INVITE F5 |
| 100 F6 |--------------->|
Message Details π
F1 INVITE Alice -> Redirect Server
INVITE sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/UDP client.atlanta.example.com:5060;branch=z9hG4bKbf9f44
Max-Forwards: 70
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl
To: Bob <sip:bob@biloxi.example.com>
Call-ID: 2xTb9vxSit55XU7p8@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com>; index=1
Contact: <sip:alice@client.atlanta.example.com>
Content-Length: 0
F2 302 Moved Temporarily Redirect Proxy -> Alice
SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP client.atlanta.example.com:5060;branch=z9hG4bKbf9f44
;received=192.0.2.1
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl
To: Bob <sip:bob@biloxi.example.com>;tag=53fHlqlQ2
Call-ID: 2xTb9vxSit55XU7p8@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com>; index=1
Contact: <sip:bob@chicago.example.com;transport=tcp>
Content-Length: 0
F3 ACK Alice -> Redirect Server
ACK sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/UDP client.atlanta.example.com:5060;branch=z9hG4bKbf9f44
Max-Forwards: 70
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl
To: Bob <sip:bob@biloxi.example.com>;tag=53fHlqlQ2
Call-ID: 2xTb9vxSit55XU7p8@atlanta.example.com
CSeq: 1 ACK
Content-Length: 0
F4 INVITE Alice -> Proxy 3
INVITE sip:bob@chicago.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
Max-Forwards: 70
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl
To: Bob <sip:bob@biloxi.example.com>
Call-ID: 2xTb9vxSit55XU7p8@atlanta.example.com
CSeq: 2 INVITE
History-Info: <sip:bob@biloxi.example.com?Reason=SIP;cause=302>\
text="Moved Temporarily">; index=1,
<sip:bob@chicago.example.com>; index=2
Contact: <sip:alice@client.atlanta.example.com;transport=tcp>
Content-Length: 0
F5 INVITE Proxy 3 -> Bob
INVITE sip:bob@client.chicago.example.com SIP/2.0
Via: SIP/2.0/TCP ss3.chicago.example.com:5060;branch=z9hG4bK721e.1
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.1
Max-Forwards: 69
Record-Route: <sip:ss3.chicago.example.com;lr>
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl
To: Bob <sip:bob@biloxi.example.com>
Call-ID: 2xTb9vxSit55XU7p8@atlanta.example.com
CSeq: 2 INVITE
History-Info: <sip:bob@biloxi.example.com?Reason=SIP;cause=302>\
text="Moved Temporarily">; index=1,
<sip:bob@chicago.example.com>; index=2,
<sip:bob@client.chicago.example.com>; index=2.1
Contact: <sip:alice@client.atlanta.example.com;transport=tcp>
Content-Length: 0
Detailed Call Flow continues per section 6.3 in [RFC3665].
Editor's Address π
Mary Barnes
Nortel
2201 Lakeside Blvd
Richardson, TX USA
Phone: 1-972-684-5432
EMail: mary.barnes@nortel.com
Full Copyright Statement π
Copyright (C) The Internet Society (2005).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property π
The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.
Acknowledgement π«Ά
Funding for the RFC Editor function is currently provided by the Internet Society.
π¦ where this page comes from
- ietf: rfc4244 2005-11
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms