RFC 7131

Session Initiation Protocol (SIP) History-Info Header Call Flow Examples

πŸ“… published March 2014, from ietf

Session Initiation Protocol (SIP) History-Info Header Call Flow Examples πŸŽ€

Okay bestie, this one is all about the History-Info header in SIP πŸ“žβœ¨. It's from March 2014 and it was written by M. Barnes, F. Audet, S. Schubert, H. van Elburg, and C. Holmberg 🫢. The authors are from Skype, NTT, Detecon International Gmbh, and Ericsson, which is a seriously strong group. It's published by the IETF as an Informational document, so it's not a Standards Track spec, and it has ISSN 2070-1721 🌸. The title block doesn't list anything this RFC obsoletes or updates, so it stands on its own πŸ’….

Session Initiation Protocol (SIP) History-Info Header Call Flow Examples

Abstract

okay so the whole point of this doc is to show use cases and call flows where the History-Info header needs to record the Request-URIs as a SIP Request gets retargeted πŸ¦‹. Every use case comes with a call flow diagram and the messaging details, so you can actually see what's happening πŸ‘€πŸ’–.

Status of This Memo

ngl this part is the legal-ish bit, but it's important πŸ™ˆ. This document is not an Internet Standards Track specification. It's published for informational purposes only 🌈.

It's a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) ✨. Not every IESG-approved document is a candidate for any level of Internet Standard, so check Section 2 of RFC 5741 if you want the details 🧚.

Info about the current status of this document, any errata, and how to give feedback is at http://www.rfc-editor.org/info/rfc7131 πŸ’œ.

Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved πŸ”₯.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they were in effect on the date of publication πŸ’…. Please read these carefully, because they describe your rights and restrictions for this document. Any Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty as described in the Simplified BSD License πŸŽ€.

Table of Contents

1. Overview ........................................................2
2. Conventions and Terminology .....................................3
3. Detailed Call Flows .............................................3
   3.1. Sequentially Forking (History-Info in Response) ............3
   3.2. History-Info with Privacy Header Field ....................11
   3.3. Privacy for a Specific History-Info Entry .................16
   3.4. Automatic Call Distribution ...............................20
   3.5. Determining the Alias Used ................................27
   3.6. PBX Voicemail Example .....................................29
   3.7. Consumer Voicemail Example ................................35
   3.8. GRUU ......................................................41
   3.9. Limited-Use Address .......................................44
   3.10. Service Invocation .......................................47
   3.11. Toll-Free Number .........................................48
4. Security Considerations ........................................51
5. Acknowledgements ...............................................51
6. Informative References .........................................51

1. Overview ✨

Lowkey, a lot of SIP services need to figure out why and how a call got to a specific application 🧐. The use cases in this document show how the History-Info header [RFC7044] gets used, with examples of applications and common scenarios πŸ’–. You get example use cases, call flow diagrams, and messaging details for each one.

The optional rc and mp header field parameters defined in [RFC7044] are required for several of the use cases πŸ“. So keep an eye out for them, they're kind of a big deal πŸ‘‘.

2. Conventions and Terminology πŸ¦‹

Here's the vocab πŸ“š. The term "retarget" is used as defined in [RFC7044]. The terms "location service", "redirect", and "address-of-record (AOR)" are used consistently with the terminology in [RFC3261] 🫢.

3. Detailed Call Flows 🧚

Okay so this section has sample use cases for the History-Info header, and it's for informational purposes only 🌸. They are not intended to be normative, so they aren't the rulebook. In a lot of cases, only the relevant messaging details are included in the body of the call flow, so don't be confused if the flows look a little trimmed πŸ’…βœ¨.

3.1. Sequentially Forking (History-Info in Response) πŸ“

Okay so this scenario is the one that shows why History-Info in the response is so useful for whoever started the request πŸ’–

Alice calls Bob via sip:example.com. The proxy at sip:example.com tries Bob one destination at a time (sequential forking, bestie 🧚). First it tries a SIP User Agent (UA) that has bound a contact to the sip:bob@example.com AOR. Then it tries a couple of alternate addresses, Office and Home. Nothing picks up, so the proxy sends a response back to Alice ✨ The hi-entry containing the initial contact is the hi-entry just before the first hi-entry tagged with an "rc" header field parameter. The hi-entries themselves are identified by the index in the "mp" hi-target-param header field parameter.

Office and Home are not the same AOR as sip:bob@example.com πŸ™ˆ They're different AORs that were set up as alternate addresses for Bob in the proxy. Office and Home never get bound through SIP Registration with Bob's AOR. This is super common when someone manually configures a routing rule to a Public Switched Telephone Network (PSTN) number in a proxy, so it's giving very real-world vibes πŸ“ž

Here's the iconic part πŸ‘‘ When Alice gets the History-Info back, she (or an app on her side) can decide how to find Bob without hitting the same destination over and over. Once the response with the History-Info entries shows up, the Request-URIs of the entries tagged with an "mp" header field parameter get extracted. Those can be compared with any other URIs Alice might try, and that means no extra INVITE to Bob's home phone 🏠

Without this, Alice might try the office phone first, which retargets the request to Bob's home phone. When that fails, she might dial the home phone directly and hit it a third time, totally unknowingly πŸ’€ Avoiding that is main character energy πŸ’…

Figure 1: Example with Sequential Forking

 Alice   example.com            Bob     Office    Home

 |            |                  |        |        |
 | INVITE F1  |                  |        |        |
 |----------->|    INVITE F2     |        |        |
 |            |----------------->|        |        |
 | 100 Trying F3                 |        |        |
 |<-----------|  302 Move Temporarily F4  |        |
 |            |<-----------------|        |        |
 |            |   ACK F5         |        |        |
 |            |----------------->|        |        |
 |            |       INVITE F6           |        |
 |            |-------------------------->|        |
 |            |      180 Ringing F7       |        |
 |            |<--------------------------|        |
 |  180 Ringing F8                        |        |
 |<-----------|   retransmit INVITE       |        |
 |            |-------------------------->|        |
 |            |      ( timeout )          |        |
 |            |             INVITE F9              |
 |            |----------------------------------->|
 |            |           100 Trying F10           |
 |            |<-----------------------------------|
 |            |           486 Busy Here F11        |
 |            |<-----------------------------------|
 |  486 Busy Here F12                              |
 |<-----------|             ACK F13                |
 |            |----------------------------------->|
 |  ACK F14   |                                    |
 |----------->|                                    |

Message Details ✨

F1 INVITE Alice -> example.com

INVITE sip:bob@example.com SIP/2.0
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F2 INVITE example.com -> Bob

INVITE sip:bob@192.0.2.4 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx3st
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
Record-Route: <sip:proxy.example.com;lr>
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4>;index=1.1;rc=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F3 100 Trying example.com -> Alice

SIP/2.0 100 Trying
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
Content-Length: 0

F4 302 Moved Temporarily Bob -> example.com

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx3st
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=es43sd
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4>;index=1.1;rc=1
Contact: <sip:office@example.com>;mp=1
Content-Length: 0

F5 ACK example.com -> Bob

ACK sip:bob@example.com SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx3st
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=es43sd
Call-ID: 12345600@example.com
CSeq: 1 ACK
Content-Length: 0

F6 INVITE example.com -> office

INVITE sip:office@192.0.2.5 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx4st
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
Record-Route: <sip:proxy.example.com;lr>
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4?Reason=SIP%3Bcause%3D302>;\
              index=1.1;rc=1
History-Info: <sip:office@example.com>;index=1.2;mp=1
History-Info: <sip:office@192.0.2.5>;index=1.2.1;rc=1.2
CSeq: 1 INVITE
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F7 180 Ringing office -> example.com

SIP/2.0 180 Ringing
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx4st
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=53rdds
Supported: histinfo
Call-ID: 12345600@example.com
Record-Route: <sip:proxy.example.com;lr>
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4?Reason=SIP%3Bcause%3D302>;\
              index=1.1;rc=1
History-Info: <sip:office@example.com>;index=1.2;mp=1
History-Info: <sip:office@192.0.2.5>;index=1.2.1;rc=1.2
CSeq: 1 INVITE
Contact: Office <sip:office@192.0.2.5>
Content-Length: 0

F8 180 Ringing example.com -> Alice

SIP/2.0 180 Ringing
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=53rdds
Supported: histinfo
Call-ID: 12345600@example.com
Record-Route: <sip:proxy.example.com;lr>
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4?Reason=SIP%3Bcause%3D302>;\
              index=1.1;rc=1
History-Info: <sip:office@example.com>;index=1.2;mp=1
History-Info: <sip:office@192.0.2.5>;index=1.2.1;rc=1.2
CSeq: 1 INVITE
Contact: Office <sip:office@192.0.2.5>
Content-Length: 0

F9 INVITE example.com -> home

INVITE sip:home@192.0.2.6 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx5st
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
Record-Route: <sip:proxy.example.com;lr>
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4?Reason=SIP%3Bcause%3D302>;\
              index=1.1;rc=1
History-Info: <sip:office@example.com?Reason=SIP%3Bcause%3D408>;\
              index=1.2;mp=1
History-Info: <sip:office@192.0.2.5?Reason=SIP%3Bcause%3D408>;\
              index=1.2.1;rc=1.2
History-Info: <sip:home@example.com>;index=1.3;mp=1
History-Info: <sip:home@192.0.2.6>;index=1.3.1;rc=1.3
CSeq: 1 INVITE
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F10 100 Trying home -> example.com

SIP/2.0 100 Trying
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx5st
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>
Call-ID: 12345600@example.com
CSeq: 1 INVITE
Content-Length: 0

F11 486 Busy Here home -> example.com

SIP/2.0  486 Busy Here
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx5st
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=55rdds
Call-ID: 12345600@example.com
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4?Reason=SIP%3Bcause%3D302>;\
              index=1.1;rc=1
History-Info: <sip:office@example.com?Reason=SIP%3Bcause%3D408>;\
              index=1.2;mp=1
History-Info: <sip:office@192.0.2.5?Reason=SIP%3Bcause%3D408>;\
              index=1.2.1;rc=1.2
History-Info: <sip:home@example.com>;index=1.3;mp=1
History-Info: <sip:home@192.0.2.6>;index=1.3.1;rc=1.3
CSeq: 1 INVITE
Content-Length: 0

F12 486 Busy Here example.com -> Alice

SIP/2.0  486 Busy Here
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=55rdds
Call-ID: 12345600@example.com
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.4?Reason=SIP%3Bcause%3D302>;\
              index=1.1;rc=1
History-Info: <sip:office@example.com?Reason=SIP%3Bcause%3D408>;\
              index=1.2;mp=1
History-Info: <sip:office@192.0.2.5?Reason=SIP%3Bcause%3D408>;\
              index=1.2.1;rc=1.2
History-Info: <sip:home@example.com>;index=1.3;mp=1
History-Info: <sip:home@192.0.2.6>;index=1.3.1;rc=1.3
CSeq: 1 INVITE
Content-Length: 0

F13 ACK example.com -> home

ACK sip:home@192.0.2.6 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKx5st
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=55rdds
Call-ID: 12345600@example.com
CSeq: 1 ACK
Content-Length: 0

F14 ACK Alice -> example.com

ACK sip:bob@example.com SIP/2.0
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=sr3dds
To: Bob <sip:bob@example.com>;tag=55rdds
Call-ID: 12345600@example.com
Route: <sip:proxy.example.com;lr>
CSeq: 1 ACK
Content-Length: 0

3.2. History-Info with Privacy Header Field ✨

okay bestie, this one is all about the Privacy header field with the value history πŸ”. An intermediary adds it, and the intermediary in charge of the biloxi.example.com domain is the one doing it πŸ’…. Once it's there, all the History-Info header field information gets anonymized outside biloxi.example.com. Privacy stays locked down. 🫢

     Alice  atlanta.example.com  biloxi.example.com  Bob Work  Bob Home

     |             |                |                 |          |
     | INVITE F1   |                |                 |          |
     |------------>|                |                 |          |
     |             |                |                 |          |
     |             |   INVITE F2    |                 |          |
     |             |--------------->|                 |          |
     |             |                |                 |          |
     |             |                | INVITE F3       |          |
     |             |                |---------------->|          |
     |             |                |302 Move Temporarily F4     |
     |             |                |<----------------|          |
     |             |                |    ACK F5       |          |
     |             |                |---------------->|          |
     |             |                |                 |          |
     |             |                | INVITE F6       |          |
     |             |                |--------------------------->|
     |             |                |     200 F7      |          |
     |             |                |<---------------------------|
     |             |                |                 |          |
     |             |     200 F8     |                 |          |
     |             |<---------------|                 |          |
     |             |                |                 |          |
     |     200 F9  |                |                 |          |
     |<------------|                |                 |          |
     |             |                |                 |          |
     |             |       ACK      |                 |          |
     |---------------------------------------------------------->|
     |             |                |                 |          |

              Figure 2: Example with Privacy Header Fields

Message Details

F1 INVITE Alice -> atlanta.example.com

INVITE sip:bob@biloxi.example.com;p=x SIP/2.0
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 70
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>
Supported: histinfo
Privacy: history
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F2 INVITE atlanta.example.com -> biloxi.example.com

INVITE sip:bob@biloxi.example.com;p=x SIP/2.0
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 69
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F3 INVITE biloxi.example.com -> Bob Work

INVITE sip:bob@192.0.1.11 SIP/2.0
Via: SIP/2.0/TCP proxy.biloxi.example.com:5060;branch=z9hG4bKgs33
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.3
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 68
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>
Privacy: history
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1
History-Info: <sip:bob@192.0.1.11>;index=1.1.1;rc=1.1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F4 302 Moved Temporarily Bob Work -> biloxi.example.com

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/TCP proxy.biloxi.example.com:5060;branch=z9hG4bKgs33;\
                 received=192.0.2.102
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.3
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=11
Privacy: history
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1
History-Info: <sip:bob@192.0.1.11>;index=1.1.1;rc=1.1
Contact: Bob Home <sip:bob@192.0.1.15>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F5 ACK biloxi.example.com -> Bob Work

ACK sip:bob@192.0.1.11 SIP/2.0
Via: SIP/2.0/TCP proxy.biloxi.example.com:5060;branch=z9hG4bKgs33
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.3
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 68
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=11
Call-ID: 12345600@atlanta.example.com
CSeq: 1 ACK
Content-Length: <appropriate value>

[SDP Not Shown]

F6 INVITE biloxi.example.com -> Bob Home

INVITE sip:bob@192.0.1.15 SIP/2.0
Via: SIP/2.0/TCP proxy.biloxi.example.com:5060;branch=z9hG4bKgs32
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.3
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 68
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>
Privacy: history
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1
History-Info: <sip:bob@192.0.1.11?Reason=SIP%3Bcause%3D302>;\
                index=1.1.1;rc=1
History-Info: <sip:bob@192.0.1.15>;index=1.1.2
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F7 200 OK Bob -> biloxi.example.com

SIP/2.0 200 OK
Via: SIP/2.0/TCP proxy.biloxi.example.com:5060;branch=z9hG4bKgs32;\
               received=192.0.2.101
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.3
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=33
Privacy: history
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1
History-Info: <sip:bob@192.0.1.11?Reason=SIP%3Bcause%3D302>;\
                index=1.1.1;rc=1
History-Info: <sip:bob@192.0.1.15>;index=1.1.2;rc=1.1
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F8 200 OK biloxi.example.com -> atlanta.example.com

SIP/2.0 200 OK
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.3
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=33
Privacy: history
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:anonymous@anonymous.invalid>;index=1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1.1;rc=1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1.2;rc=1.1
Contact: Bob <sip:bob@192.0.1.11>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F9 200 OK atlanta.example.com -> Alice

SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=33
Privacy: history
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:anonymous@anonymous.invalid>;index=1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1.1;rc=1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1.2;rc=1.1
Contact: Bob <sip:bob@192.0.1.11>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

3.3. Privacy for a Specific History-Info Entry ✨

okay so this one is basically the same vibe as Section 3.2 πŸŽ€ but there's a twist! 🫣 the local policy at sip:biloxi.example.com says only the final hi-entry gets a privacy header field with a priv-value of "history". so Alice still gets some info about how the request traveled πŸ—ΊοΈ, but Bob's local URI gets anonymized πŸ™ˆ it's giving "I'll tell you the journey, not the destination's real name" πŸ’…

Alice atlanta.example.com biloxi.example.com Bob

   Alice   atlanta.example.com  biloxi.example.com   Bob
   |                |                |                |
   |   INVITE F1    |                |                |
   |--------------->|                |                |
   |                |                |                |
   |                |   INVITE F2    |                |
   |                |--------------->|                |
   |                |                |                |
   |                |                | INVITE F3      |
   |                |                |--------------->|
   |                |                |                |
   |                |                |     200 F4     |
   |                |                |<---------------|
   |                |                |                |
   |                |     200 F5     |                |
   |                |<---------------|                |
   |                |                |                |
   |     200 F6     |                |                |
   |<---------------|                |                |
   |                |                |                |
   |                |       ACK      |                |
   |------------------------------------------------->|
   |                |                |                |

       Figure 3: Example with Privacy Header Field for Specific URI

Message Details πŸ“

F1 INVITE Alice -> atlanta.example.com πŸ’–

INVITE sip:bob@biloxi.example.com;p=x SIP/2.0
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 70
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F2 INVITE atlanta.example.com -> biloxi.example.com πŸ¦‹

INVITE sip:bob@biloxi.example.com;p=x SIP/2.0
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 69
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1;np=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F3 INVITE biloxi.example.com -> Bob 🧚

INVITE sip:bob@192.0.1.11 SIP/2.0
Via: SIP/2.0/TCP proxy.biloxi.example.com:5060;branch=z9hG4bKeset
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
Max-Forwards: 68
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1;np=1
History-Info: <sip:bob@192.0.1.11?Privacy=history>;index=1.1.1;rc=1.1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F4 200 OK Bob -> biloxi.example.com 🌸

SIP/2.0 200 OK
Via: SIP/2.0/TCP proxy.biloxi.example.com:5060;branch=z9hG4bKeset;\
               received=192.0.2.5
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=33
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1;np=1
History-Info: <sip:bob@192.0.1.11?Privacy=history>;index=1.1.1;rc=1.1
Contact: Bob <sip:bob@192.0.1.11>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F5 200 OK biloxi.example.com -> atlanta.example.com πŸ‘‘

SIP/2.0 200 OK
Via: SIP/2.0/TCP proxy.atlanta.example.com:5060;branch=z9hG4bKbst2;\
               received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=33
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1;np=1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1.1;rc=1.1
Contact: Bob <sip:bob@192.0.1.11>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F6 200 OK atlanta.example.com -> Alice 🫢

SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK4321
From: Alice <sip:alice@atlanta.example.com>;tag=22
To: Bob <sip:bob@biloxi.example.com>;tag=33
Supported: histinfo
Call-ID: 12345600@atlanta.example.com
CSeq: 1 INVITE
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1
History-Info: <sip:bob@biloxi.example.com;p=x>;index=1.1;np=1
History-Info: <sip:anonymous@anonymous.invalid>;index=1.1.1;rc=1.1
Contact: Bob <sip:bob@192.0.1.11>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

3.4. Automatic Call Distribution ✨

Okay bestie, this scenario is an Automatic Call Distribution service πŸ“žπŸ’– Agents get split into groups based on the kind of customers they handle. Gold customers get priority over Silver customers, so a Gold call still gets serviced even if every agent in the Gold group is busy. The request gets retargeted to the Silver group so an agent can pick it up 🫢

When the call lands on the agent, the History-Info header tells the app that it's a Gold call. The app grabs the hi-entry tied to the incoming request, which is the hi-entry whose index is reflected in the first hi-entry with a hi-target of "mp" πŸ¦‹ In this example, that's the hi-entry referenced by the value of the first "mp" header field parameter, aka the hi-entry with an index of "1". The app can also figure out how many groups the call may have overflowed through before reaching the agent, and show all that info to the agent so they can handle it nicely: "I'm so sorry for the delay, blah, blah, blah..." πŸ’…

Now for calls that overflow from Silver to Gold πŸ‘€ the alternate group identification, internal routing, or actual agent handling the call should not be sent to UA1. So for this scenario, the proxy would not support sending the History-Info in the response, even if Alice asks for it. Another option is that the proxy could anonymize the Silver-related hi-entries by adding privacy to them πŸ™ˆ

Just like the other examples, this isn't a complete recipe for this kind of service. It's a sample of some of the processing that might go along with it 🧚 Also, this example doesn't cover agent availability that sends the call to an agent in a different group, which might also happen over a SIP interface.

   Alice       example.com     Gold          Silver       Agent

   |              |              |             |            |
   | INVITE F1    |              |             |            |
   |------------->|              |             |            |
   |              |              |             |            |
   |              |  INVITE F2   |             |            |
   |              |------------->|             |            |
   |              |              |             |            |
   |              |  302 Moved Temporarily F3  |            |
   |              |<-------------|             |            |
   |              |              |             |            |
   |              |      ACK     |             |            |
   |              |------------->|             |            |
   |              |              |             |            |
   |              |  INVITE F4   |             |            |
   |              |--------------------------->|            |
   |              |              |             |            |
   |              |              |             | INVITE F5  |
   |              |              |             |----------->|
   |              |              |             |            |
   |              |              |             |  200 OK F6 |
   |              |              |             |<-----------|
   |              |              |             |            |
   |              |         200 OK F7          |            |
   |              |<---------------------------|            |
   |              |              |             |            |
   |  200 OK F8   |              |             |            |
   |<-------------|              |             |            |
   |              |              |             |            |
   |                         ACK F9                         |
   |------------------------------------------------------->|

           Figure 4: Example for Automatic Call Distribution

Message Details πŸŽ€

F1 INVITE Alice -> example.com

INVITE sip:Gold@example.com SIP/2.0
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F2 INVITE example.com -> Gold.example.com

INVITE sip:Gold@gold.example.com SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
History-Info: <sip:Gold@gold.example.com>;rc=1;index=1.1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F3 302 Moved Temporarily Gold.example.com -> example.com

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4;\
               received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>;tag=kkaz-
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
History-Info: <sip:Gold@gold.example.com>;rc=1;index=1.1
Contact: <sip:Silver@example.com>;mp=1
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F4 INVITE example.com -> Silver.example.com

INVITE sip:Silver@example.com SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK45q2
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
History-Info: <sip:Gold@gold.example.com?Reason=SIP%3Bcause%3D302>;\
                rc=1;index=1.1
History-Info: <sip:Silver@example.com>;index=1.2;mp=1
History-Info: <sip:Silver@silver.example.com>;index=1.2.1;rc=1.2
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F5 INVITE Silver.example.com -> Agent

INVITE sip:Silver@192.0.2.7 SIP/2.0
Via: SIP/2.0/TCP silver.example.com:5060;branch=z9hG4bKerxs
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK45q2;\
               received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 68
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
History-Info: <sip:Gold@gold.example.com?Reason=SIP%3Bcause%3D302>;\
                rc=1;index=1.1
History-Info: <sip:Silver@example.com>;index=1.2;mp=1
History-Info: <sip:Silver@silver.example.com>;index=1.2.1;rc=1.2
History-Info: <sip:Silver@192.0.2.7>;index=1.2.1.1;rc=1.2.1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F6 200 OK Agent -> Silver.example.com

SIP/2.0 200 OK
Via: SIP/2.0/TCP silver.example.com:5060;branch=z9hG4bKerxs;\
                received=192.0.2.5
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK45q2;\
                received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>;tag=2325
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
History-Info: <sip:Gold@gold.example.com?Reason=SIP%3Bcause%3D302>;\
                rc=1;index=1.1
History-Info: <sip:Silver@example.com>;index=1.2;mp=1
History-Info: <sip:Silver@silver.example.com>;index=1.2.1;rc=1.2
History-Info: <sip:Silver@192.0.2.7>;index=1.2.1.1;rc=1.2.1
Contact: Agent <sip:Silver@192.0.2.7>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F7 200 OK Silver.example.com -> example.com

SIP/2.0 200 OK
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK45q2;\
                received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>;tag=2325
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
History-Info: <sip:Gold@gold.example.com?Reason=SIP%3Bcause%3D302>;\
                rc=1;index=1.1
History-Info: <sip:Silver@example.com>;index=1.2;mp=1
History-Info: <sip:Silver@silver.example.com>;index=1.2.1;rc=1.2
History-Info: <sip:Silver@192.0.2.7>;index=1.2.1.1;rc=1.2.1
Contact: Agent <sip:Silver@192.0.2.7>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F8 200 OK example.com -> Alice

SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>;tag=2325
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:Gold@example.com>;index=1
History-Info: <sip:Gold@gold.example.com?Reason=SIP%3Bcause%3D302>;\
                rc=1;index=1.1
History-Info: <sip:Silver@example.com>;index=1.2;mp=1
History-Info: <sip:Silver@silver.example.com>;index=1.2.1;rc=1.2
History-Info: <sip:Silver@192.0.2.7>;index=1.2.1.1;rc=1.2.1
Contact: Agent <sip:Silver@192.0.2.7>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F9 ACK Alice -> Agent

ACK sip:Silver@192.0.2.7 SIP/2.0
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t3
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=1235
To: Gold Member Assistance <sip:Gold@example.com>;tag=2325
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 ACK
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

The first hi-entry with the "mp" header field parameter has an "mp" header field parameter value of 1, which points to the original-target 🎯 That's how the operator can tell the call came from the Gold customer, and honestly that's so iconic πŸ‘‘βœ¨

3.5. Determining the Alias Used πŸ’…

okay so SIP UAs are tied to an AOR, right? but a single UA can actually have multiple AORs attached to it 🫢 the most common version of this is aliases. like, a user might have sip:john@example.com and ALSO sip:john.smith@example.com and sip:jsmith@example.com. instead of registering against every single one (ain't nobody got time for that 😭), the user just registers against ONE of them, and the home proxy quietly accepts incoming calls for any of the aliases, treats them all the same, and forwards them along to the UA. this is super common in the IP Multimedia Subsystem (IMS), where it's called "implicit registration" and each alias is called a "public user identity (PUID)" 🧚

now, a UAS getting a call needs to know which alias was used to reach it. literally so important πŸ‘‘ it's how you pick a ringtone, decide how to treat the call, and so on. for example, someone could give one alias ONLY to friends and family, so when that one rings you get a special ring that's like "pick up, this matters" πŸ”₯

the call flow and example messages below show how History-Info can help figure out which alias got used to reach the callee. the alias is the one in the hi-entry whose index matches the last hi-entry that has an "rc" header field parameter in the Request that was received. iykyk πŸ™ˆ

       Alice             example.com             John
       |                     | REGISTER F1         |
       |                     |<--------------------|
       |                     | 200 OK F2           |
       |                     |-------------------->|
       | INVITE F3           |                     |
       |-------------------->|                     |
       |                     | INVITE F4           |
       |                     |-------------------->|
                   * Rest of flow not shown *

                    Figure 5: Alias Example

Message Details ✨

F1 REGISTER John -> example.com πŸŽ€

REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/TCP 192.0.2.1;branch=z9hG4bKnashds7
Max-Forwards: 70
From: John <sip:john@example.com>;tag=a73kszlfl
To: John <sip:john@example.com>
Supported: histinfo
Call-ID: 1j9FpLxk3uxtm8tn@192.0.2.1
CSeq: 1 REGISTER
Contact: <sip:john@192.0.2.1>
Content-Length: 0

F2 200 OK example.com -> John 🌸

SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.0.2.1;branch=z9hG4bKnashds7
From: John <sip:john@example.com>;tag=a73kszlfl
To: John <sip:john@example.com>;tag=d2dstee2
Call-ID: 1j9FpLxk3uxtm8tn@192.0.2.1
CSeq: 1 REGISTER
Contact: <sip:john@192.0.2.1>;expires=3600
Content-Length: 0

F3 INVITE Alice -> example.com πŸ¦‹

INVITE sip:john.smith@example.com SIP/2.0
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=a73kszlfl
To: John <sip:john.smith@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:john.smith@example.com>;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F4 INVITE example.com -> John πŸ’–

INVITE sip:john@192.0.2.1 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=a73kszlfl
To: John <sip:john.smith@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
Record-Route: <sip:proxy.example.com;lr>
History-Info: <sip:john.smith@example.com>;index=1
History-Info: <sip:john@192.0.2.1>;index=1.1;rc=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]
ngl this is the key moment πŸ”₯ the last hi-entry with the "rc" header field parameter is the one that points at the source of the retargeting, and in this example that source is the alias AOR, which is "john.smith@example.com" πŸ’œ

3.6. PBX Voicemail Example ✨

okay so voicemail is the classic use case πŸ“ž the original person you called is not reachable, so the call lands in a voicemail system. sometimes it bounces through a few alternate destinations first and nobody picks up 😭 the voicemail system (VMS) usually needs to know who the call was originally for, so it can play the right greeting and tell the right person they have a message πŸ’Œ

in this example, Alice calls Bob, but Bob's SIP client is forwarded to Carol πŸŽ€ Carol doesn't answer, so the call gets forwarded to a VM (voicemail) server (VMS) 🧚 to pick the right mailbox, the VMS needs the original target of the request. to find that, you look for the first hi-entry tagged with "rc" or "mp" and then use the hi-entry referenced by the index in the "rc" or "mp" header field parameter as the target for choosing the mailbox πŸ’… that hi-entry gets used to fill in the "target" URI parameter from [RFC4458]. the reason on that first "rc" or "mp" hi-entry (that's the 302) can be used to make a custom voicemail greeting, and it gets stuffed into the "cause" URI parameter from [RFC4458] too πŸ¦‹ some VMSs might also (or instead) look at the History-Info headers to handle the VM differently based on how and why the call showed up there πŸ‘‘

also, it's the proxy that forwards the call to the VMS who decides the target of the voicemail 🫢 that proxy sets the voicemail target, and it's also the one that uses [RFC7044] to find the target, which is usually based on local policy that a user or admin installed. no cap, main character energy for the proxy πŸ”₯

Here's the whole flow:

Alice      example.com       Bob          Carol        VM

   | INVITE F1    |              |             |          |
   |------------->|              |             |          |
   |              | INVITE  F2   |             |          |
   |              |------------->|             |          |
   |              |              |             |          |
   |  100 Trying  |              |             |          |
   |<-------------| 302 Moved Temporarily F3   |          |
   |              |<-------------|             |          |
   |              |              |             |          |
   |              |      ACK     |             |          |
   |              |------------->|             |          |
   |              |              |             |          |
   |              | INVITE F4    |             |          |
   |              |--------------------------->|          |
   |              |              |             |          |
   |              |         180 Ringing  F5    |          |
   |              |<---------------------------|          |
   |              |              |             |          |
   | 180 Ringing  |              |             |          |
   |<-------------|              |             |          |
   |              |              |             |          |
   |              |       (timeout)            |          |
   |              |              |             |          |
   |              | INVITE  F6   |             |          |
   |              |-------------------------------------->|
   |              |              |             |          |
   |              |               200 OK  F7              |
   |              |<--------------------------------------|
   |   200 OK     |              |             |          |
   |<-------------|              |             |          |
   |              |              |             |          |
   |                         ACK                          |
   |----------------------------------------------------->|

Figure 6: Enterprise Voicemail Example

Message Details

F1 INVITE Alice -> example.com πŸ’–

INVITE sip:bob@example.com SIP/2.0
Via: SIP/2.0/TCP  192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=kkaz-
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Length: <appropriate value>

[SDP Not Shown]

F2 INVITE example.com -> Bob 🌸

INVITE sip:bob@192.0.2.5 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=kkaz-
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.5>;index=1.1;rc=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F3 302 Moved Temporarily Bob -> example.com πŸ¦‹

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4;\
                 received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
From: Alice <sip:alice@example.com>;tag=kkaz-
To: Bob <sip:bob@example.com>;tag=2g22d-lnf
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.5>;index=1.1;rc=1
Contact: <sip:carol@example.com>;mp=1
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F4 INVITE example.com -> Carol ✨

INVITE sip:carol@192.0.2.4 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK4522
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=kkaz-
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302>;\
                   index=1.1;rc=1
History-Info: <sip:carol@example.com;cause=480>;index=1.2;mp=1
History-Info: <sip:carol@192.0.2.4;cause=480>;index=1.2.1;rc=1.2
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F5 180 Ringing Carol -> example.com πŸ”₯

SIP/2.0 180 Ringing
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK4522;\
                 received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
From: Alice <sip:alice@example.com>;tag=kkaz-
To: Bob <sip:bob@example.com>;tag=setss3x
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302>;\
                   index=1.1;rc=1
History-Info: <sip:carol@example.com;cause=480>;index=1.2;mp=1
History-Info: <sip:carol@192.0.2.4;cause=480>;index=1.2.1;rc=1.2
Contact: <sip:carol@192.0.2.4>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F6 INVITE example.com -> VM πŸ’œ

INVITE sip:vm@192.0.2.6;target=sip:bob%40example.com;cause=480\
                     SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK4523
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=kkaz-
To: Bob <sip:bob@example.com>
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302>;\
                    index=1.1;rc=1
History-Info: <sip:carol@example.com;cause=480?Reason=SIP%3Bcause%3D\
              408>;index=1.2;mp=1
History-Info: <sip:carol@192.0.2.4;cause=480?Reason=SIP%3Bcause%3D\
              408>;index=1.2.1;rc=1.2
History-Info: <sip:vm@example.com;\
                    target=sip:bob%40example.com;cause=480>;\
                    index=1.3;mp=1
History-Info: <sip:vm@192.0.2.6;\
                    target=sip:bob%40example.com;cause=480>;\
                    index=1.3.1;rc=1.3
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F7 200 OK VM -> example.com πŸŽ€

SIP/2.0 200 OK
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK4523;\
                 received=192.0.2.101
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
From: Alice <sip:alice@example.com>;tag=kkaz-
To: Bob <sip:bob@example.com>;tag=3dweggs
Supported: histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:bob@example.com>;index=1
History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302>;\
                   index=1.1;rc=1
History-Info: <sip:carol@example.com;cause=480?Reason=SIP%3Bcause%3D\
              408>;index=1.2;mp=1
History-Info: <sip:carol@192.0.2.4;cause=480?Reason=SIP%3Bcause%3D\
              408>;index=1.2.1;rc=1.2
History-Info: <sip:vm@example.com;\
                   target=sip:bob%40example.com;cause=480>;\
                   index=1.3;mp=1
History-Info: <sip:vm@192.0.2.6;\
                   target=sip:bob%40example.com;cause=480>;\
                   index=1.3.1;rc=1.3
Contact: <sip:vm@192.0.2.6>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]
the VMS just checks the last hi-entry, then reads the URI in its "target" URI parameter to find the mailbox πŸ“¬ that's literally it, bestie πŸ™ˆ

3.7. Consumer Voicemail Example πŸŽ€

okay so, for a consumer, when the call gets retargeted it's usually going to another administrative domain 🌸 And the voicemail system in those setups usually needs the last-called-party info to figure out which mailbox it's supposed to use, so it can play the right greeting and tell the right person they've got a message πŸ’Œ

Here's the situation: Alice calls Bob, but Bob has temporarily forwarded his phone to Carol (she's his wife) πŸ’• Carol doesn't pick up, so the call gets forwarded to a VMS ✨ To pick the right mailbox, the VMS needs the right target for the request. The last target is found by looking up the hi-entry that the index of the last hi-entry tagged with "mp" points to, and that's the hi-entry for picking the mailbox 🧚 This hi-entry is used to fill in the target URI parameter defined in [RFC4458]. Also, some VMSs may (or may not, depending on the setup) use the info in the History-Info headers to do custom handling of the VM, like how and why the call ended up at the VMS πŸ¦‹

   Alice      example.com       Bob          Carol        VM

   | INVITE F1    |              |             |          |
   |------------->|              |             |          |
   |              | INVITE  F2   |             |          |
   |              |------------->|             |          |
   |              |              |             |          |
   |  100 Trying  |              |             |          |
   |<-------------| 302 Moved Temporarily F3   |          |
   |              |<-------------|             |          |
   |              |              |             |          |
   |              |      ACK     |             |          |
   |              |------------->|             |          |
   |              |              |             |          |
   |              | INVITE F4    |             |          |
   |              |--------------------------->|          |
   |              |              |             |          |
   |              |         180 Ringing  F5    |          |
   |              |<---------------------------|          |
   |              |              |             |          |
   | 180 Ringing  |              |             |          |
   |<-------------|              |             |          |
   |              |              |             |          |
   |              |       (timeout)            |          |
   |              |              |             |          |
   |              | INVITE  F6   |             |          |
   |              |-------------------------------------->|
   |              |              |             |          |
   |              |               200 OK  F7              |
   |              |<--------------------------------------|
   |   200 OK     |              |             |          |
   |<-------------|              |             |          |
   |              |              |             |          |
   |                         ACK                          |
   |----------------------------------------------------->|

                  Figure 7: Consumer Voicemail Example

Message Details ✨

F1 INVITE Alice -> example.com

   INVITE sip:bob@example.com SIP/2.0
   Via: SIP/2.0/TCP  192.0.2.3:5060;branch=z9hG4bK42t2
   Max-Forwards: 70
   From: Alice <sip:alice@example.com>;tag=kkaz-
   To: Bob <sip:bob@example.com>
   Supported: histinfo
   Call-ID: 12345600@example.com
   CSeq: 1 INVITE
   History-Info: <sip:bob@example.com>;index=1
   Contact: Alice <sip:alice@192.0.2.3>
   Content-Length: <appropriate value>

   [SDP Not Shown]

F2 INVITE example.com -> Bob

   INVITE sip:bob@192.0.2.5 SIP/2.0
   Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4
   Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
   Max-Forwards: 69
   From: Alice <sip:alice@example.com>;tag=kkaz-
   To: Bob <sip:bob@example.com>
   Supported: histinfo
   Call-ID: 12345600@example.com
   CSeq: 1 INVITE
   History-Info: <sip:bob@example.com>;index=1
   History-Info: <sip:bob@192.0.2.5>;index=1.1;rc=1
   Contact: Alice <sip:alice@192.0.2.3>
   Content-Type: application/sdp
   Content-Length: <appropriate value>

   [SDP Not Shown]

F3 302 Moved Temporarily Bob -> example.com

   SIP/2.0 302 Moved Temporarily
   Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4;\
           received=192.0.2.101
   Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
   From: Alice <sip:alice@example.com>;tag=kkaz-
   To: Bob <sip:bob@example.com>;tag=224ls3s-t
   Supported: histinfo
   Call-ID: 12345600@example.com
   CSeq: 1 INVITE
   History-Info: <sip:bob@example.com>;index=1
   History-Info: <sip:bob@192.0.2.5>;index=1.1;rc=1
   Contact: <sip:carol@example.com>;mp=1
   Content-Type: application/sdp
   Content-Length: <appropriate value>

   [SDP Not Shown]

F4 INVITE example.com -> Carol

   INVITE sip:carol@192.0.2.4 SIP/2.0
   Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK24s5
   Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
   Max-Forwards: 69
   From: Alice <sip:alice@example.com>;tag=kkaz-
   To: Bob <sip:bob@example.com>
   Supported: histinfo
   Call-ID: 12345600@example.com
   CSeq: 1 INVITE
   History-Info: <sip:bob@example.com>;index=1
   History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302\
                 %3Btext%3D%22Moved%20Temporarily%22>\
                 ;index=1.1;rc=1
   History-Info: <sip:carol@example.com>;index=1.2;mp=1
   History-Info: <sip:carol@192.0.2.4>;index=1.2.1;rc=1.2
   Contact: Alice <sip:alice@192.0.2.3>
   Content-Type: application/sdp
   Content-Length: <appropriate value>

   [SDP Not Shown]

F5 180 Ringing Carol -> example.com

   SIP/2.0 180 Ringing
   Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK24s5;\
           received=192.0.2.101
   Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
   From: Alice <sip:alice@example.com>;tag=kkaz-
   To: Bob <sip:bob@example.com>;tag=setss3x
   Supported: histinfo
   Call-ID: 12345600@example.com
   CSeq: 1 INVITE
   History-Info: <sip:bob@example.com>;index=1
   History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302\
                 %3Btext%3D%22Moved%20Temporarily%22>;\
                 index=1.1;rc=1
   History-Info: <sip:carol@example.com>;index=1.2;mp=1
   History-Info: <sip:carol@192.0.2.4>;index=1.2.1;rc=1.2
   Contact: <sip:carol@192.0.2.4>
   Content-Type: application/sdp
   Content-Length: <appropriate value>

   [SDP Not Shown]

F6 INVITE example.com -> VM

   INVITE sip:vm@192.0.2.6;target=sip:carol%40example.com SIP/2.0
   Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKbbg4
   Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
   Max-Forwards: 69
   From: Alice <sip:alice@example.com>;tag=kkaz-
   To: Bob <sip:bob@example.com>
   Supported: histinfo
   Call-ID: 12345600@example.com
   CSeq: 1 INVITE
   History-Info: <sip:bob@example.com>;index=1
   History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302\
                 %3Btext%3D%22Moved%20Temporarily%22>;\
                 index=1.1;rc=1
   History-Info: <sip:carol@example.com>;\
                 index=1.2;mp=1
   History-Info: <sip:carol@192.0.2.4?Reason=SIP%3Bcause%3D408>;\
                 index=1.2.1;rc=1.2
   History-Info: <sip:vm@example.com;target=sip:carol%40example.com;\
                 cause=408>;index=1.2.2;mp=1.2
   History-Info: <sip:vm@192.0.2.5;target=sip:carol%40example.com;\
                 cause=408>;index=1.2.2.1;rc=1.2.2
   Contact: Alice <sip:alice@192.0.2.3>
   Content-Type: application/sdp
   Content-Length: <appropriate value>

   [SDP Not Shown]

F7 200 OK VM -> example.com

   SIP/2.0 200 OK
   Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bKbbg4
   Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
   From: Alice <sip:alice@example.com>;tag=kkaz-
   To: Bob <sip:bob@example.com>;tag=3dweggs
   Supported: histinfo
   Call-ID: 12345600@example.com
   CSeq: 1 INVITE
   History-Info: <sip:bob@example.com>;index=1
   History-Info: <sip:bob@192.0.2.5?Reason=SIP%3Bcause%3D302\
                 %3Btext%3D%22Moved%20Temporarily%22>;\
                 index=1.1;rc=1
   History-Info: <sip:carol@example.com>;\
                 index=1.2;mp=1
   History-Info: <sip:carol@192.0.2.4?Reason=SIP%3Bcause%3D408>;\
                 index=1.2.1;rc=1.2
   History-Info: <sip:vm@example.com;target=sip:carol%40example.com;\
                 cause=408>;index=1.2.2;mp=1.2
   History-Info: <sip:vm@192.0.2.5;target=sip:carol%40example.com;\
                 cause=408>;index=1.2.2.1;rc=1.2.2
   Contact: <sip:carol@192.0.2.5>
   Content-Type: application/sdp
   Content-Length: <appropriate value>

   [SDP Not Shown]

The VMS can check the last hi-entry πŸ” It grabs the mailbox target from the target URI parameter in that hi-entry, and the reason from the cause URI parameter in the same hi-entry πŸ’… main character VMS behaviour, honestly 🌈

3.8. GRUU πŸŽ€

okay so this one is a sequel to the problem in Section 3.5 😭 A GRUU (Globally Routable User Agent URI) [RFC5627] is a URI given to one specific UA instance. It acts a lot like the AOR, but requests sent to it only get routed to that exact instance πŸ’… Why does the UA care? Because it's really useful to know whether someone called its GRUU or its AOR. That can drive different authorization policies, like deciding whether to accept or reject the request πŸ”₯ The tea is that, just like the AOR, the GRUU gets lost in translation at the home proxy. So the UAS can't tell whether it was contacted via the GRUU or its AOR πŸ’€

Here's the call flow and example messages showing how History-Info can help us figure out which GRUU was used to reach the callee ✨

A GRUU is an AOR with a URI parameter, as defined in [RFC5627], but the GRUU construct itself is not an AOR 🧚 So when a request gets retargeted based on a GRUU, no "rc" header field parameter gets added to the hi-entry containing the GRUU. A missing "rc" header field parameter in the hi-entries can be a hint that the retargeting came from a GRUU πŸ‘€ But to make sure, the UAS needs to search for a "gr" parameter in the hi-entry before the last hi-entry. If there's a GRUU, that URI will always come before the last hi-entry, because a GRUU doesn't let multiple instances map to one contact address πŸ¦‹

       Alice             example.com             John
       |                     | REGISTER F1         |
       |                     |<--------------------|
       |                     | 200 OK F2           |
       |                     |-------------------->|
       | INVITE F3           |                     |
       |-------------------->|                     |
       |                     | INVITE F4           |
       |                     |-------------------->|
                    * Rest of flow not shown *

                      Figure 8: GRUU Example

Message Details

F1 REGISTER John -> example.com

REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.0.2.1;branch=z9hG4bKnashds7
Max-Forwards: 70
From: John <sip:John@example.com>;tag=a73kszlfl
Supported: gruu
To: John <sip:john@example.com>
Call-ID: 1j9FpLxk3uxtm8tn@192.0.2.1
CSeq: 1 REGISTER
Contact: <sip:john@192.0.2.1>;+sip.instance=\
    <urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>
Content-Length: 0

[SDP Not Shown]

F2 200 OK example.com -> John

SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.0.2.1;branch=z9hG4bKnashds7
From: John <sip:john@example.com>;tag=a73kszlfl
To: John <sip:john@example.com> ;tag=b88sn
Call-ID: 1j9FpLxk3uxtm8tn@192.0.2.1
CSeq: 1 REGISTER
Contact: <sip:john@192.0.2.1>;\
    pub-gruu="sip:john@example.com;\
    gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6";\
    temp-gruu=\
    "sip:tgruu.7hs==jd7vnzga5w7fajsc7-ajd6fabz0f8g5@example.com;\
  gr";+sip.instance=\
    "<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>";\
    expires=3600
  Content-Length: 0

[SDP Not Shown]

Assuming Alice already knows a GRUU, from earlier communication or from something like presence, she places a call to John's GRUU πŸ“ž

F3 INVITE Alice -> example.com

INVITE sip:john@example.com;\
    gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 SIP/2.0
Via: SIP/2.0/TCP  192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=kkaz-
To: <sip:john@example.com;\
    gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>
Supported: gruu, histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: <sip:john@example.com;\
    gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Length: <appropriate value>

[SDP Not Shown]

F4 INVITE example.com -> John

INVITE sip:john@192.0.2.1 SIP/2.0
Via: SIP/2.0/TCP proxy.example.com:5060;branch=z9hG4bK12s4
Via: SIP/2.0/TCP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=kkaz-
To: <sip:john@example.com;\
    gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>
Supported: gruu, histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
Record-Route: <sip:proxy.example.com;lr>
History-Info: <sip:john@example.com;\
    gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>;index=1
History-Info: <sip:john@192.0.2.1>;index=1.1;rc=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

The trick is this: look at the entry referenced by the one with the last "rc" πŸ•΅οΈβ€β™€οΈ If it has a "gr" parameter, you know the URI used to reach the device was a GRUU. Main character detective energy, periodt ✨

3.9. Limited-Use Address πŸ¦‹

A limited-use address is a SIP URI minted on demand and handed out to a small number of remote correspondents (usually just one) πŸ’Œ Incoming calls to that address get accepted for as long as the UA still wants to hear from that remote target. If they're no longer welcome in your life πŸ™…β€β™€οΈ, the URI gets invalidated so future requests to it are rejected. Bye, bestie πŸ‘‹

Limited-use addresses are used to fight voice spam [RFC5039] πŸ›‘οΈ The easiest way to make them would be for a UA to take its AOR and "mint" a limited-use address by appending extra parameters to the URI. It can then give that URI to one particular correspondent and remember it locally. When an incoming call shows up, the UAS checks the parameter in the URI and decides whether the call should be accepted. Or, the UA could push authorization rules into the network, so it never even has to see the requests it's going to reject πŸ™ˆ

This approach, especially when it's done on the UA, needs the parameters attached to the AOR (but not used by the home proxy when processing the request) to survive the translation at the home proxy and get presented to the UA. That's not going to happen with the logic in RFC 3261, because the Request-URI gets replaced by the registered contact and those parameters are lost 😀

With History-Info, John's UA can easily see whether the call was addressed to its AOR, its GRUU, or a temp-GRUU, and handle the call accordingly. It does this by looking for a "gr" tag in the hi-entry before the last hi-entry ✨

       Alice             example.com             John
       |                     | REGISTER F1         |
       |                     |<--------------------|
       |                     | 200 OK F2           |
       |                     |-------------------->|
       | INVITE F3           |                     |
       |-------------------->|                     |
       |                     | INVITE F4           |
       |                     |-------------------->|
                    * Rest of flow not shown *

              Figure 9: Limited-Use Address Example

Message Details

F1 REGISTER John -> example.com

REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.0.2.1;branch=z9hG4bKnashds7
Max-Forwards: 70
From: John <sip:John@example.com>;tag=a73kszlfl
Supported: gruu
To: John <sip:john@example.com>
Call-ID: 1j9FpLxk3uxtm8tn@192.0.2.1
CSeq: 1 REGISTER
Contact: <sip:john@192.0.2.1>;\
  +sip.instance="<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>"
Content-Length: 0

F2 200 OK example.com -> John

SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.0.2.1;branch=z9hG4bKnashds7
From: John <sip:john@example.com>;tag=a73kszlfl
To: John <sip:john@example.com> ;tag=b88sn
Call-ID: 1j9FpLxk3uxtm8tn@192.0.2.1
CSeq: 1 REGISTER
Contact: <sip:john@192.0.2.1>;\
  pub-gruu="sip:john@example.com;\
  gr=urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6";\
  temp-gruu=\
  "sip:tgruu.7hs==jd7vnzga5w7fajsc7-ajd6fabz0f8g5@example.com;gr";\
  +sip.instance="<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>";\
  expires=3600
Content-Length: 0

Assuming Alice knows a temp-GRUU, she places a call to that temp-GRUU πŸ“±

F3 INVITE Alice -> example.com

INVITE sip:tgruu.7hs==jd7vnzga5w7fajsc7-ajd6fabz0f8g5@example.com;\
    gr SIP/2.0
Via: SIP/2.0/UDP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=kkaz-
To: <sip:tgruu.7hs==jd7vnzga5w7fajsc7-ajd6fabz0f8g5@example.com\
 ;gr>
Supported: gruu, histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
History-Info: \
 <sip:tgruu.7hs==jd7vnzga5w7fajsc7-ajd6fabz0f8g5@example.com;gr>\
 ;index=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Length: <appropriate value>

F4 INVITE example.com -> John

INVITE sip:john@192.0.2.1 SIP/2.0
Via: SIP/2.0/UDP proxy.example.com:5060;branch=z9hG4bK12s4
Via: SIP/2.0/UDP 192.0.2.3:5060;branch=z9hG4bK42t2
Max-Forwards: 69
From: Alice <sip:alice@example.com>;tag=kkaz-
To: <sip:tgruu.7hs==jd7vnzga5w7fajsc7-ajd6fabz0f8g5@example.com\
 ;gr>
Supported: gruu, histinfo
Call-ID: 12345600@example.com
CSeq: 1 INVITE
Record-Route: <sip:proxy.example.com;lr>
History-Info: \
 <sip:tgruu.7hs==jd7vnzga5w7fajsc7-ajd6fabz0f8g5@example.com;gr>\
 ;index=1
History-Info: <sip:john@192.0.2.1>;index=1.1;rc=1
Contact: Alice <sip:alice@192.0.2.3>
Content-Type: application/sdp
Content-Length: <appropriate value>

Same deal as before: check the entry referenced by the one with the last "rc", and if it has a "gr" parameter, the URI used to reach the device was a GRUU 🎯

3.10. Service Invocation πŸ’–

Lots of SIP specifications use complex URIs to address services inside the network instead of subscribers 🧚 These URIs get complicated because they pack in loads of parameters that control how the service behaves. Examples include the spec that first introduced the concept [RFC3087], control of network announcements and Interactive Voice Response (IVR) with SIP URI [RFC4240], and control of voicemail access with SIP URI [RFC4458] πŸ“Ό

The shared problem here is this: once a proxy has decided to rewrite the Request-URI to point at the service, it can't be sure that the Request-URI won't get destroyed by a downstream proxy that decides to forward the request and rewrites the Request-URI again 😰

Section 3.6 shows how History-Info can be used to invoke a service πŸ’…

3.11. Toll-Free Number ☎️✨

Okay bestie, toll-free numbers are the 800 or 8xx numbers in the US πŸ’– They're the ones that are free for the caller to dial πŸ“ž

In the phone network, a toll-free number is basically just an alias for a real number that the call gets routed to πŸ¦‹ To process the call in the PSTN, a switch runs a query using a protocol called Transaction Capabilities Application Part (TCAP). The answer is either a phone number or the identity of a carrier that can handle the call πŸ’…

There's been recent work on letting SIP proxy servers access these PSTN translation services through IP querying mechanisms 🌈 For example, ENUM [RFC6117] has already been proposed as a way to do Number Portability (NP) queries [RFC4769]. Using it for 8xx number translations is the logical next step 🧚

The new target after translating an 8xx number could be in the PSTN or in the SIP network 🌸 If it's in the PSTN, the proper treatment there (especially correct reconciliation of billing records) requires that the call be marked with both the originating number (the 8xx number) and the new target number. This is where History-Info comes in to make sure the original 8xx number doesn't get lost πŸ”₯

If the call stays in the SIP network, you don't have to carry both the originating number and the new target πŸ’… But an enterprise or user who uses the 8xx service can benefit from knowing the call came in through an 8xx number, so they can treat it differently (for example, by playing a special announcement) πŸŽ€ The problem is that if the original Request-URI gets lost during translation, there's no way to tell the call came in via an 8xx number. Guess who saves the day again? History-Info πŸ’œ

Similar problems show up with other "special" numbers and services in the PSTN, like operator services, pay/premium numbers (9xx numbers in the United States), and short service codes such as 311 πŸ™ˆ

To find the service number, the UAS can pull out the hi-entry whose index matches the value of the first hi-entry with an "mp" tag πŸ‘‘ Technically, a call can be forwarded from a non-special number to these "special" numbers, but that's uncommon because of the way these services authorize translations πŸ€”

Here's an example call flow where the UAC doesn't support History-Info πŸŽ€

        Alice      Toll-Free Service   Atlanta.com          John
         |                |              |                   |
         |    INVITE F1   |              |                   |
         |--------------->|   INVITE F2  |                   |
         |                |------------->|                   |
         |                |              |  INVITE F3        |
         |                |              |------------------>|

                      * Rest of flow not shown *

                  Figure 10: Service Number Example

Message Details πŸ“¬

F1 INVITE 192.0.2.1 -> Toll-Free Service

INVITE sip:+18005551002@example.com;user=phone  SIP/2.0
Via: SIP/2.0/TCP 192.0.2.1:5060;branch=z9hG4bK74bf
From: Alice <sip:+15551001@example.com;user=phone>;tag=9fxced76sl
To: <sip:+18005551002@example.com;user=phone>
Call-ID: c3x842276298220188511
CSeq: 1 INVITE
Max-Forwards: 70
Contact: <sip:alice@192.0.2.1>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F2 INVITE Toll-Free Service -> Atlanta.com

INVITE sip:+15555551002@atlanta.com SIP/2.0
Via: SIP/2.0/TCP 192.0.2.4:5060;branch=z9hG4bK-ik8
Via: SIP/2.0/TCP 192.0.2.1:5060;branch=z9hG4bK74bf
From: Alice <sip:+15551001@example.com;user=phone>;tag=9fxced76sl
To: <sip:+18005551002@example.com;user=phone>
Call-ID: c3x842276298220188511
CSeq: 1 INVITE
Max-Forwards: 69
Supported: histinfo
History-Info: <sip:+18005551002@example.com;user=phone>;index=1
History-Info: <sip:+15555551002@atlanta.com>;index=1.1;mp=1
Contact: <sip:alice@192.0.2.1>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

F3 INVITE Atlanta.com -> John

INVITE sip:john@198.51.100.2 SIP/2.0
Via: SIP/2.0/TCP 198.51.100.1:5060;branch=z9hG4bKpxk7g
Via: SIP/2.0/TCP 192.0.2.4:5060;branch=z9hG4bK-ik8
Via: SIP/2.0/TCP 192.0.2.1:5060;branch=z9hG4bK74bf
From: Alice <sip:+15551001@example.com;user=phone>;tag=9fxced76sl
To: <sip:+18005551002@example.com;user=phone>
Call-ID: c3x842276298220188511
CSeq: 1 INVITE
Max-Forwards: 68
Supported: histinfo
History-Info: <sip:+18005551002@example.com;user=phone>;index=1
History-Info: <sip:+15555551002@atlanta.com>;index=1.1;mp=1
History-Info: <sip:john@atlanta.com>;index=1.1.1;rc=1.1
History-Info: <sip:john@198.51.100.2>;index=1.1.1.1;rc=1.1.1
Contact: <sip:alice@192.0.2.1>
Content-Type: application/sdp
Content-Length: <appropriate value>

[SDP Not Shown]

4. Security Considerations πŸ”

Security stuff, bestie, and it's serious 😭 The security considerations for the History-Info header field are specified in [RFC7044]. Go read that one before you ship anything πŸ’€

5. Acknowledgements 🫢

Jonathan Rosenberg, et al produced the document that brought up extra use cases, and those use cases are what led to the new "target" parameter in the History-Info header field and the new SIP/SIPS URI parameter 🌟 Hadriel Kaplan also left some comments πŸ’œ

Brett Tate, Roland Jesske, Laura Liess, Scott Godin, Dale Worley, and Marianne Mohali did extensive review and gave comments on the call flows, message examples, and text. Absolute legends πŸ‘‘

6. Informative 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.
  • [RFC5627] Rosenberg, J., "Obtaining and Using Globally Routable User Agent URIs (GRUUs) in the Session Initiation Protocol (SIP)", RFC 5627, October 2009.
  • [RFC3087] Campbell, B. and R. Sparks, "Control of Service Context using SIP Request-URI", RFC 3087, April 2001.
  • [RFC4240] Burger, E., Van Dyke, J., and A. Spitzer, "Basic Network Media Services with SIP", RFC 4240, December 2005.
  • [RFC5039] Rosenberg, J. and C. Jennings, "The Session Initiation Protocol (SIP) and Spam", RFC 5039, January 2008.
  • [RFC4458] Jennings, C., Audet, F., and J. Elwell, "Session Initiation Protocol (SIP) URIs for Applications such as Voicemail and Interactive Voice Response (IVR)", RFC 4458, April 2006.
  • [RFC6117] Hoeneisen, B., Mayrhofer, A., and J. Livingood, "IANA Registration of Enumservices: Guide, Template, and IANA Considerations", RFC 6117, March 2011.
  • [RFC4769] Livingood, J. and R. Shockey, "IANA Registration for an Enumservice Containing Public Switched Telephone Network (PSTN) Signaling Information", RFC 4769, November 2006.
  • [RFC7044] Barnes, M., Audet, F., Schubert, S., van Elburg, J., and C. Holmberg, "An Extension to the Session Initiation Protocol (SIP) for Request History Information", RFC 7044, February 2014.

Authors' Addresses πŸ¦‹

Mary Barnes
TX
US

EMail: mary.ietf.barnes@gmail.com


Francois Audet
Skype

EMail: francois.audet@skype.net


Shida Schubert
NTT
Tokyo
Japan

EMail: shida@ntt-at.com


Hans Erik van Elburg
Detecon International Gmbh
Oberkasseler str. 2
Bonn
Germany

EMail: ietf.hanserik@gmail.com


Christer Holmberg
Ericsson
Hirsalantie 11, Jorvas
Finland

EMail: christer.holmberg@ericsson.com

That's the whole RFC, bestie! 🌈✨ You made it through all 10 parts πŸ’–

πŸ“¦ where this page comes from