Subject: Re: [Insipid] draft-ietf-insipid-session-id-14: comments and questions

From: "Paul Giralt (pgiralt)" <[email-masked]>
Date: Sun, 20 Dec 2015 04:21:41 +0000

Brett,

Thank you for your comments. Paul Jones has asked me to take over editorship duties for this draft in the hopes of driving it to publication. Apologies for the delay in responding.

I’ve read through your comments and I agree with many of your points. In the end, most of them revolve around one central issue which is how intermediaries (and to some extent endpoints) are supposed to deal with the Session ID when an error condition occurs, primarily for mid-dialog changes to a session (e.g. re-INVITE or UPDATE for example). While the text as it stands basically tries to state that an endpoint or intermediary should attempt to update the stored UUID if it is able to do so, as you have pointed out there is some ambiguity to what this means and enumerating every error condition and the expected handling of the Session ID for each condition would be challenging at best.

I propose a simpler solution that should address your concerns and make it easy for implementers to understand what should be done in these scenarios. This would require a slight modification to the draft as it stands today. I am therefore seeking your and the working group’s approval to move forward with this change. If we can all agree on this in concept, I will put together some concrete text for inclusion in the draft.

In a nutshell, I propose that we make a minor change to the text to explicitly call out the conditions under which a UUID should be stored by endpoints and intermediaries. I propose that an endpoint or intermediary only store an updated remote UUID under the following conditions:

When receiving a request (other than ACK) that is accepted (results in a 1XX or 2XX response), the received UUID must be retained. If the request results in any other kind of response, it should not be retained. This can, of course, lead to conditions where a request is received, a provisional response is sent (and therefore the UUID is retained) and then for whatever reason, an error (4XX/5XX/6XX) or redirect (3XX) response is sent. In such a case, we will never “roll back” the Session ID.

The only additional rule for stateful intermediaries is that if they accept a request and then forward that request to another destination (therefore there was no error found with the message), this will also trigger the intermediary to update the retained UUID.

The remote UUID in all responses must match the UUID received in the request if the SIP stack is able to process the Session-ID header. This applies even if the UUID is not going to be retained. If a re-INVITE {C,B} contains an error but the Session-ID is successfully extracted from the re-INVITE, the 4XX response should contain {B,C} (assuming the receiving endpoint is still using B as the local UUID. Otherwise B should be replaced with the correct Local UUID).

To deal with issues where a response with a Session ID different than what is being retained is sent in an error response and the ACK for that response contains the new Session ID which we chose not to retain because it was as a result of an error, the document will state that a Session ID received in an ACK must never update the retained value. This should never be an issue because the Session ID in the ACK should always match that of the matching request, so if the endpoint receiving the request updated the Session ID on the request, it does not need to do so again for the ACK.

Endpoints and intermediaries always update their Remote Session ID based on any responses received regardless of the type of response (provided the response is syntactically valid and can be processed, of course).

There will always be feature interactions that result in temporarily mismatched Session IDs when intermediaries are involved, but I don’t think the above proposal makes this any worse of a problem in real-world applications.

Please see my responses inline to address your concerns….

I'm glad to hear that this draft doesn't alter the processing rules.
Draft-ietf-insipid-session-id-16 currently appears to violate (or alter) RFC
3261 section 8.2: "If it is rejected, all state changes MUST NOT be
performed".  Similarly it also appears to impact the following RFC 6141
section 3.3 SHOULD: "If any of the changes requested in a re-INVITE or in
any transaction within it have already been executed, the UAS SHOULD return
a 2xx response".

One of the ways to fix the "MUST NOT" violation would be to explain what
may/should/must occur when rejecting (and handling rejected) mid-dialog
requests such as re-INVITE which contained an updated local-UUID.  It should
be clarified within sections 6 and 7.

I believe the above proposal addresses this.

> If a message is received and determined to be valid and
> processed, the UUID is updated -- if there is a new UUID.

It sounds like that changes the processing rules of RFC 3261 (unless
"processed" excludes error situations); see above.

Again, I believe this is addressed in the proposal because the UUID is only updated when the message is processed successfully. Any error conditions will not result in the updated UUID being retained.

> >Unknown or unsupported request situations are
> >interesting.  Even though the request is unknown or
> >unsupported, the draft still mandates allowing it to
> >update the UUID.
>
> One could interpret it that way, though one could equally
> not update the UUID given the message could not be
> processed.  I think it's a matter of whether you trust
> the message to be valid.

If you are leaving it to the vendors to decide if "MUST" really means "MUST"
(which might be a reason to change some "MUST" to "SHOULD" or a reason to
provide clarification of processing steps before hitting the "MUST"), the
intermediaries and endpoints may disagree about the current Session-ID.

Consider dialog's Session-ID which is currently {A,B} while an intermediary
is used.  If something sends FOO with {C,B} (i.e. changing local-UUID)
through intermediary which gets rejected by B with 501 response, what does
draft-ietf-insipid-session-id-16 say MUST occur?  It looks like section 6
paragraphs 3 and 6 indicate that the 501 must include {B,C} within the 501.
It looks like RFC 3261 processing rules (if not altering them) would cause
the 501 to contain 1) remote-UUID A, 2) remote-UUID C but deem A as current,
or 3) include no Session-ID and deem A as current.

Draft-ietf-insipid-session-id-16 currently appears to cause the intermediary
to think that the UUID changed from A to C.  Should intermediaries follow
RFC 3261 section 8.2 and think that the failure responses caused a rollback
of the UUID?  If so and re-INVITE, does the rollback occur before or after
sending the corresponding ACK?

Based on the proposal above, for your example, the correct behavior will be your option 2. Re-INVITE would contain {C,B}, the 501 would contain {B,C} (But C is not stored), and ACK would contain {C,B} (but C is not stored on the ACK). If the intermediary decides to generate a re-INVITE towards the endpoint that sent the original re-INVITE, it must send {A,B} for the Session-ID.

> No, I think you're reading too much into this.  No
> sensible implementation of any protocol should result in
> accepting a known malformed message and pulling out parts
> of it for use.  If the message is clearly malformed, then
> the whole thing should be junked.  That's not even
> something that should have to be said at this point.  If
> the message is malformed, the UA should send a 400, not
> try to pull out some part of a malformed message and use it.

It sounds like your opinion has changed from your January 8 reply which
sounded like 4xx situations were no different from 2xx situations.

http://www.ietf.org/mail-archive/web/insipid/current/msg00975.html

What should be the remote-UUID that draft-ietf-insipid-session-id-16
currently mandates to include within the response?  It looks like section 6
paragraphs 3 and 6 currently mandate Session-ID and remote-UUID reflect the
value within the malformed message.

If the Session-ID header is processed successfully, yes, it should be used to construct the Session-ID header in the response, however this does not mean it needs to update the stored value. In the above proposal, the stored value would not be updated.

Similarly if the malformed re-INVITE traversed an intermediary, what should
be the local-UUID within 400's ACK built by intermediary?  It looks like
section 7 would cause the ACK's local-UUID to be the value included within
the malformed re-INVITE.  And it looks like section 6 paragraphs 3 and 6
currently mandate allowing the 400's ACK update the stored remote-UUID.

If the malformed re-INVITE contains a Session-ID of {C,B} and the intermediary can reliably extract this from the message, the 400 will contain {B,C} in the response. The resulting ACK would again contain {C,B} but C would not be stored.

> >Large SIP message situations are interesting.  Even
> >though a device might reject large messages, the draft
> >still mandates processing the message enough to update
> >the UUID.
>
> No, I don't think that's the case.  If a large message
> is rejected, I would not expect the UA to go pull out
> the UUID and use it.  This is similar to the malformed
> message case.  The SIP stack is going to parse the
> message or discard messages long before the message gets
> to the state machine where it would deal with UUIDs.

Sounds good.  Draft-ietf-insipid-session-id should be updated to quit
mandating the different behavior.

I believe there should be a statement to the effect that a received Session-ID header should be used in the error response if it can reliably be extracted, but regardless of whether it is able to be used for the response, it must not be stored.

> >>>Since CANCEL can contain an older UUID, it potentially
> >>>isn't the best choice for inclusion as the remote-uuid.
> >
> >You should likely discuss the impacts of CANCEL if you
> >are really intending to allow it to roll back the UUID.
> >Otherwise, implementers might not think that the draft
> >truly intended for the rollback to occur.
>
> There is no intent for it to roll back a UUID.   The UA
> sending the CANCEL will use the original UUID is used
> before, but it will not include the "remote" part.  That
> was a change we made in a recent draft -- it has to match
> the orginal INVITE.

The "remote" part doesn't cause a change; thus I'm less concerned about it
being old or incorrect.

For fun, session starts as {A,B}.  The re-INVITE is sent with {C,B}; UPDATE
is sent with {D,B} and resulted in 2xx response for UPDATE.  The CANCEL
would indicate {C,B}.  As far as I know, the
draft-ietf-insipid-session-id-16 indicates that B must consider the
remote-UUID to be C (because of CANCEL); and if the draft doesn't want to
update RFC 3261, sending the 487 response implies that B should consider the
remote-UUID to subsequently be A (although RFC 3261 is vague about the
potential for failure response's ACK to update stored data).

In this case I would expect the 487 to be {B,C}. I’m not sure why you think it should be A. In this case, following the proposed changes, the error response (487 in this case) must use the Session-ID from the request (the re-INVITE). No solution is perfect, but I think the proposal is very deterministic and clear as to what the expected behavior should be.

> >>>Because of race conditions, the "most recently received
> >>>UUID" is not necessarily the most recent UUID sent by
> >>>the remote endpoint.
> >
> >Potentially addressed good enough.  However, adding a
> >statement about race conditions within the draft would
> >help silence complaints if anyone was thinking that the
> >draft provides a way to ensure all of the devices truly
> >know the current Session-ID.
>
> The only case, I think, where this is an issue is with
> certain service interaction.  And this is called out in
> the examples (e.g., in 9.3).  It is shown how to address
> this problem.  Maybe "race condition" was not the right
> term to use, but I don't think there are any problems
> with the current procedures in this regard.

This document contains many MUST statements concerning devices without much
clarification concerning when they specifically apply and if ever rolled
back.  Similarly because this draft allows UUID modification to be caused by
things like CANCEL, non-2xxx-ACK, and responses, the potential for race
conditions and unintentional modifications are more common than only
allowing things like target refresh requests and reliable responses (such as
within RFC 6141) to change the stored UUID.

As I mentioned, adding a statement about race conditions within the draft
would help silence complaints if anyone was thinking that the draft provides
a way to ensure all of the devices truly know the current Session-ID.

I believe the proposal addresses most of these issues, but if you have any proposed text that would help clarify race conditions, please let me know. There will inherently be situations where the current Session-ID may be mismatched temporarily. We could certainly explicitly call this out better.

> >>>If a device returns 500 because lower CSeq, it seems
> >>>strange that the UAS MUST update the stored UUID.
> >
> >Potentially addressed good enough since I don't think
> >implementers would interpret "peer endpoint MAY change
> >at any time" as including requests containing lower cseq.
>
> Indeed.  This did not mean to throw out all logical
> message processing ;-)

The joy of reading MUST statements out of context; even with statements like
"PRACK is like any other request within a dialog, and the UAS core processes
it according to the procedures of Sections 8.2 and 12.2.2 of RFC 3261" some
vendors interpret RFC 3262 as though you can't even return a 500 response
for PRACK.

Because this draft doesn't appear to follow the typical 3xx-6xx rules, the
draft's intended mandatory behavior is not always obvious.

What remote-UUID should be included within 500 response generated because of
lower cseq: A) local-UUID from request being rejected, or B) stored
remote-UUID?  Based upon your reply, it sounds like the answer is B.  I
guess that the answer would also be B within the PRACK situation where UAS
needs to return 200 instead of 500 (for the cseq issue) because of
interoperability reasons.

Hopefully the proposal makes this clear as well. The answer would be A) local-UUID from request being rejected (but the value would not be stored). The PRACK case is interesting because you are saying it is generating an error, but returning a 200 anyway. This seems like a corner case.

> >>>If the "most recently received UUID" hasn't passed
> >>>authentication (i.e. returning 401, 407, or 403),
> >>>should the request (or the related ACK) still be
> >>>allowed to alter the stored UUID?
> >
> >As far as I know, the draft indicates yes.  Is this
> >acceptable?
>
> If it's a valid response, yes.  If the UA sends an
> INVITE with {A,N} and gets a 407 with {A,B}, then it
> should accept {B} if the 407 isn't bogus.

My question was from the UAS perspective: "should the request (or the
related ACK) still be allowed to alter the stored UUID?”

In the proposed solution, no, the request (and the ACK) are not allowed to alter the stored UUID.

> >>>If an overloaded device returns a failure response
> >>>(such as 503), is the overloaded device actually
> >>>supposed to still update the stored UUID to be
> >>>compliant with this mandate?  If this draft is
> >>>mandating an overloaded server process an
> >>>unauthenticated request to update stored information,
> >>>it should be mentioned within section 11.
> >>
> >> Whew!  OK, that's a lot to chew on. :)
> >
> >As far as I know, the draft indicates yes.  Is this
> >acceptable and should it be mentioned within section 11?
> >I'm glad that the draft only indicates that the B2BUA
> >SHOULD (instead of MUST) communicate the update to the
> >remote device.
>
> If a server is overloaded and not processing messages and,
> instead, returning 5xx, I don't expect it to update the
> UUID value.  There is an assumption here that I don't
> think needs to be stated, and that is that acceptance of
> a UUID is only done if the message is accepted and
> processed.  Malformed, 5xx, etc. errors should not mean
> we ignore all other processing and go pull out and update
> a UUID.

As mentioned earlier within this reply, I think draft clarifications are
needed.

I believe this is also addressed with the proposal.

> >>>Section 6 paragraph 2: Should clarify authentication
> >>>behavior.  For instance, RFC 3261 allows the
> >>>challenger to behave mostly stateless (such as by not
> >>>retrying 401/407); however this draft currently appears
> >>>to mandate maintaining additional information and
> >>>perform related modifications.
> >>
> >> I see value in keeping that state.  This is in line
> >> with also maintaining the UUID value even in the face
> >> of getting a 3xx, too.  We want this to effectively
> >> persist from the moment the user lifts the handset and
> >> makes a call to the moment the user hangs up the phone.
> >
> >Sounds okay from a UAC perspective; however since the
> >Call-ID can change, I don't see how that mandate is
> >always possible from a UAS perspective.
>
> From the UAS perspective, the call is over when it sends
> back a 4xx.  I only meant that the client would maintain
> this state, not the server.  If that needs clarification,
> tell me where to add it, but only the UAC should maintain
> UUID information between INVITE / 3xx, for example.

Insert a paragraph within section 6 after paragraph 2 (or text as part of
paragraph 2).  Clarify that the rejecting device MAY consider the session
completed when rejecting an INVITE associated with a non-confirmed dialog.
Thus the rejecting device is not required to continue to use the same
local-UUID after rejecting an INVITE with a 3xx-5xx response such as 401 or
305 which might cause a related subsequent INVITE to be received.

Potentially alter section 6 paragraph 4 to quit allowing the 3xx handling to
allow an endpoint to populate a non-null remote-UUID within subsequent
related INVITE when the 3xx is received outside of a confirmed dialog.  You
removed 4xx from that paragraph in version 16.

Believe this is also addressed as well.

> >>>Section 7 paragraph 3: If the intermediary knows it
> >>>is relaying the request to a different session, can
> >>>it fix the remote-uuid (such as changing it to null)?
> >>
> >> For the response aggregation case, definitely.  For
> >> what other cases are you thinking that should happen?
> >
> >Basically any cases where the B2BUA likely has a more
> >accurate view of the current remote UUID.  For instance,
> >section 9.3 example.  Similarly, the endpoint may be
> >incorrect concerning section 6's "believes may be a new
> >peer endpoint" check and included non-null remote UUID.
> >Similarly, consider race conditions (although it could
> >also cause B2BUA to be wrong).
>
> I'm struggling with what other words need to be added here.
> I don't see where things are going to go unpredictably off
> course.  We know there are cases (esp. service interaction
> cases) where the two ends might have a different view of
> the UUID values, but the B2BUA is in a position to fix the
> problem, since it likely caused the problem.
>
> If we just get rid of B2BUAs and 3PCC, we would have no
> problems. But in those cases, those devices that causes
> confusion have to fix it.

I know that the last paragraph of section 7 exists.  I'm asking if the
intermediary can fix the remote-UUID value as it relays a received message.
Section 7 paragraph 3 appears to prevent the intermediary from fixing the
remote-UUID (although the restriction complies with RFC 7206 REQ3).

Paragraph 3 ends with "except as outlined in this section” and then for the transfer / join cases, paragraph 5 states "MUST properly construct a Session-ID header field that contains the correct UUID values and correct placement of those values” which is admittedly vague in what “correct” means, but to me this implies that the intermediary is allowed to fix the UUID if it knows it needs to be fixed.

Hope that helps clarify things. Please let me know if you agree with this approach and I will work on getting some text together that solidifies this proposal.

Thanks,
-Paul