Subject: Re: [Insipid] 3pcc INSIPID backwards-compat call flows

From: "Paul E. Jones" <[email-masked]>
Date: Wed, 4 Sep 2013 23:41:44 -0400

Hadriel,

Many of these flows will work, but some will not.  Let me give you just one
example:

Suppose Alice Calls Bob.  Suppose Carol calls Bob.  We would have this:

      Session ID
         ---     Alice             Bob             Carol
        {A}        |-----INVITE---->|                |
        {A,B1}     |<-----200 OK----|                |
        {A,B1}     |------ACK------>|                |
        {C}        |                |<----INVITE-----|
                   (Put Alice on hold to answer Carol)               
        {C,B2}     |                |------200 OK--->|          
        {C,B2}     |                |<-----ACK-------|
                   (Put Carol on hold to transfer call)               

Now, Bob wants to transfer Alice to Carol.  Bob might do this by pressing a
button on the phone and either his phone or the PBX performs the local
"join".  Let's assume his PBX handles this.  This will involve sending a few
INVITE messages one way or the other, but what does Bob's PBX send to Alice?
I assume {A,C}, since Carol took Bob's place and we want to preserve the
position and value A.  And what does Bob's PBX send to Carol?  I assume {C,
A}.

This keeps the endpoints happy, but we no longer have an end-to-end
identifier as per the Kaplan draft, though we do have an end-to-end
identifier per the INSIPID draft.

Unfortunately, to make this work it forces the PBX to do even more work than
it should.  Ideally, we should just allow these UUIDs to pass straight
through without modification by the PBX.

But let's continue a little further.  Suppose Sue calls Carol and Carol
transfer the Alice/Carol call to Sue:

      Session ID
         ---     Alice             Bob             Carol             Sue
        {A,C}/{C,A}|-------Established Call----------|                |
        {S}        |                |                |<----INVITE-----|
                   (Put Alice on hold to answer Sue)               
        {S,C2}     |                |                |------200 OK--->|
        {S,C2}     |                |                |<-----ACK-------|
                                     (Put Sue on hold to transfer call)

When Carol's PBX does the join, what does it send toward Sue and what does
it send toward Bob's PBX?

What Carol's PBX was sending toward Bob's PBX and reaching Alice was {C,A}.
It cannot change that C (since we have this rule of not changing the first
value), though it could change A to S just to convey who is on the other
end.  Bob's PBX could then send {A,S} to Alice.  Carol's PBX could send {S,
A} to Sue, though it does not send "A" toward Bob.  This is really strange.

I think we have these values on the wire (arrows indicate direction):

      Session ID
         ---     Alice           Bob PBX          Carol PBX          Sue
                   |  <--{A,S}      |  <--{C,S}      |  <--{S,A}      |
                   |    {A,S}-->    |    {C,A}-->    |    {S,A}-->    |

I would say this is a most unfortunate mess.  With this approach, we can get
the two ends to agree on a value, but the intermediaries have to maintain
this ugly state.  They could log the assumed Session ID, but trying to
describe this is painful.  And, if there were any signaling devices sitting
on the path, but not taking an active role, they would be totally confused
as to what the Session ID is since there are different values going in
different directions at the interior devices (e.g., Bob-Carol in the above
example).

James and I spent some time thinking about this problem.  It's not clear
that we can ensure backward compatibility with the Kaplan draft if we get
into a flow like the one above or even more complex flows.  Implementation
would be a bear and I believe the claim that nobody would implement this
would be true.  It's just too complicated.

What we thought might be a better approach is to simply operate per the
Kaplan draft OR the INSIPID draft based on what the signaling looks like on
the wire.  It does mean more complex call flows are "broken" as far as the
Kaplan draft is concerned, but they're going to be broken, anyway, unless we
do some of that ugly stuff above.

Here's the idea:

Alice places a call using {A, null}.  The "remote" parameter would be
present and set to all zeros to indicate the Alice is compliant with the
INSIPID spec.  If the parameter is not present in a received message, then
Bob knows that Alice is a Kaplan device and would operate accordingly.

So considering the case where both Alice and Bob are both INSIPID compliant,
we have the usual flow:

      Session ID
         ---     Alice             Bob             Carol
        {A,null}   |-----INVITE---->|                |
        {B,A}      |<-----200 OK----|                |
        {B,A}      |------ACK------>|                |

If Bob does not see the remote parameter in the received INVITE (i.e., Alice
is a Kaplan device), Bob just echoes the value back and inserts "null" as
the "remote" parameter (which is useful for any subsequent transfers like we
described above). 

Consider this case where A = Kaplan and B = INSIPID:

      Session ID
         ---     Alice             Bob             Carol
        {A}        |-----INVITE---->|                |
        {A,null}   |<-----200 OK----|                |
        {A}        |------ACK------>|                |

And consider the reverse where A = INSIPID and B = Kaplan:

      Session ID
         ---     Alice             Bob             Carol
        {A,null}   |-----INVITE---->|                |
        {A}        |<-----200 OK----|                |
        {A,null}   |------ACK------>|                |

Now let's extend the above example with one where Carol is also
INSIPID-compliant and we work through the call transfer scenario from the
beginning:

      Session ID
         ---     Alice             Bob             Carol
        {A,null}   |-----INVITE---->|                |
        {A}        |<-----200 OK----|                |
        {A,null}   |------ACK------>|                |
        {C}        |                |<----INVITE-----|
                   (Put Alice on hold to answer Carol)               
        {C}        |                |------200 OK--->|          
        {C,null    |                |<-----ACK-------|
                   (Put Carol on hold to transfer call)               

At this point, we assume Bob's PBX just blindly passes the Session-ID
header.  No complex interworking.  So, what came in from Alice gets
forwarded by Bob's PBX to Carol and vice versa.  That is, Bob's PBX sends
{A,NULL} to Carol.  Carol replies with {C,A}.  {C,A} is sent to Alice.  Had
Bob's PBX sent the first message to Alice, it might have sent {C,null},
which is odd, but Alice would reply back with {A,null} and then Carol would
reply with {C,A} when it saw the presence of the "remote" parameter.  In the
end, we have both ends with the right Session-ID and the PBX remained
ignorant of the contents of the Session-ID header.

I think that greatly reduces the complexity of the intermediary devices, as
they just forward headers.  Also, it means all devices through the set of
intermediaries will be using a consistent set of values when the call is
stable.

It does mean endpoints have to operate in one of two modes depending on what
is received from the remote side.  Basically, when an endpoint replies, it
puts on the wire either the {A,null} reply (for Kaplan devices) or the {A,B}
reply (for INSIPID devices), depending on whether the remote parameter
exists in the most recently received message.  That seems far simpler to us.

Of course, the simplest solution would be to have a single logic flow and
not have to deal with the interworking issues.  I'm still open to using a
different header, personally.  And, it seems reasonable given the previous
statements that the objective of the current users of the Kaplan draft was
not to have an end-to-end identifier, but one that went SBC to SBC across a
single administrative domain.

Comments?

Paul

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf
> Of Hadriel Kaplan
> Sent: Saturday, August 17, 2013 10:08 AM
> To: [email-masked]
> Subject: [Insipid] 3pcc INSIPID backwards-compat call flows
> 
> Howdy,
> I was tasked with providing example call flows for a backwards-compatible
> Session-ID mechanism, for the call flows in the current draft-ietf-
> insipid-session-id-02.
> 
> For all the email call-flows, a syntax of "{X;Y}" means the Session-ID
> header value is 'X', while the Session-ID header parameter is 'Y'.  The
> parameter can change within a dialog, including becoming empty/no-value
> again, while the Session-ID value cannot change.
> 
> For all the email call-flows, the Section heading from the current draft
> is used, along with a copy of the intro text, to help give context.  The
> intro text has not been changed.  The call flows have been updated to show
> the new "{X;Y}" values, and in some cases additional text has been added
> below the call flow to explain specific events.
> 
> This email covers the 3PCC call flow, and the 100 Trying call flow.
> 
> --------------------------------------------------------------------------
> -
> 
> 9.7. Basic 3PCC for two UAs
> 
> 
>    External entity sets up call to both Alice and Bob for them to talk
>    to each other.
> 
>       Session ID
>          ---     Alice            B2BUA             Bob            Carol
>                    |                |                |
>          {X}       |<----INVITE-----|                |
>         {X;A}      |-----200 OK---->|                |
>          {X}       |                |----INVITE----->|
>         {X;B}      |                |<---200 OK------|
>  F1     {X;B}      |<-----ACK-------|                |
>         {X;B}      |                |------ACK------>|
>                    |<==============RTP==============>|
> 
>             Figure 8 - 3PCC initiated call between Alice and Bob
> 
> 
> F1 - Note that at this point Alice gets a new Session-ID parameter from
> the B2BUA, and this replaces the 'A' she had previously generated.  The
> Session-ID value itself of 'X' does not change.
> 
> 
> --------------------------------------------------------------------------
> -
> 
> 9.8.1. Session ID Handling in a 100 Trying SIP Response
> 
> 
>    The following 100 Trying response is taken from an existing RFC, from
> 
> [RFC5359] Section 2.9
>  ("Call Forwarding - No Answer").
> 
>     Session ID   Alice         SIP Server        Bob-1            Bob-2
>                    |                |              |                |
>        {A}         |----INVITE----->|              |                |
>        {A}         |                |---INVITE---->|                |
>        {A}         |<--100 Trying---|              |                |
>       {A;B1}       |                |<-180 Ringing-|                |
>       {A;B1}       |<--180 Ringing--|              |                |
>                    |                |              |                |
>                    |                *Request Timeout*               |
>                    |                |              |                |
>       {A;B1}       |                |---CANCEL---->|                |
>       {A;B1}       |                |<--200 OK-----|                |
>       {A;B1}       |                |<---487-------|                |
>       {A;B1}       |                |---- ACK ---->|                |
>                    |                |              |                |
>  F1    {A}         |<-181 Call Fwd--|              |                |
>                    |                |              |                |
>        {A}         |                |------------------INVITE------>|
>       {A;B2}       |                |<----------------180 Ringing---|
>  F2   {A;B2}       |<-180 Ringing---|              |                |
>       {A;B2}       |                |<-----------------200 OK ------|
>       {A;B2}       |<--200 OK-------|              |                |
>       {A;B2}       |----ACK-------->|              |                |
>       {A;B2}       |                |------------------ACK--------->|
>                    |                |              |                |
>                    |<=========== Both way RTP Established =========>|
>                    |                |              |                |
>       {A;B2}       |----BYE-------->|              |                |
>       {A;B2}       |                |--------------------BYE------->|
>       {A;B2}       |                |<------------------200 OK------|
>       {A;B2}       |<--200 OK-------|              |                |
>                    |                |              |                |
> 
>        Figure 9 - Session ID in the 100 Trying and CANCEL Messaging
> 
> F1 - Note that at this point Alice gets no Session-ID parameter from the
> SIP Server, while in a previous 180 there was a 'B1'.  Alice updates her
> stored Session-ID parameter to be empty.
> 
> F2 - Note that at this point Alice gets a new Session-ID parameter from
> the SIP Server of 'B2'.  Alice updates her stored Session-ID parameter to
> be 'B2'.
> 
> 
> -hadriel
> 
> _______________________________________________
> insipid mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/insipid

---

From: "Paul E. Jones" <[email-masked]>
Date: Thu, 5 Sep 2013 15:18:32 -0400

>         {A,null}   |------ACK------>|                |

Should be:

          {C,null}   |                |<----INVITE-----|

>         {C,null    |                |<-----ACK-------|

                 ^-- } missing here

>                    (Put Carol on hold to transfer call)

There might be another mistake somewhere... but hopefully it's clear.

Paul