RFC 6141

Re-INVITE and Target-Refresh Request Handling in the Session Initiation Protocol (SIP)

๐Ÿ“… published March 2011, from ietf

๐ŸŽ€ RFC 6141: Re-INVITE and Target-Refresh Request Handling in SIP โœจ

okay bestie, this one is from March 2011 and it's a Standards Track doc from the IETF ๐Ÿฆ‹ It's written by G. Camarillo (Ed.), C. Holmberg (Ericsson), and Y. Gao (ZTE). The ISSN is 2070-1721. It updates RFC 3261, and it's all about how SIP handles re-INVITEs and target-refresh requests. ๐Ÿ’…


Abstract ๐Ÿ’–

so RFC 3261 already explains how SIP re-INVITEs work, but once people actually built and deployed this stuff, a bunch of gaps showed up ๐Ÿ™ˆ this doc patches them. the big ones: it says when a UAS (User Agent Server) should send a success response to a re-INVITE, and when it should send an error response instead. it also goes deeper on target-refresh requests. no cap, it's giving clarity ๐ŸŒธ


Status of This Memo ๐Ÿงš

this is an Internet Standards Track document ๐Ÿ’œ

it's a product of the Internet Engineering Task Force (IETF). it reflects the consensus of the IETF community, got public review, and was approved for publication by the Internet Engineering Steering Group (IESG). if you want more on Internet Standards, check Section 2 of RFC 5741.

info about the current status of this doc, any errata, and how to send feedback lives at http://www.rfc-editor.org/info/rfc6141 ๐Ÿ“


Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿซถ

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the publication date. read these carefully, bestie, because they spell out your rights and restrictions for this doc. 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. Introduction ....................................................3
   2. Terminology .....................................................4
   3. Changing the Session State during a Re-INVITE ...................5
      3.1. Background on Re-INVITE Handling by UASs ...................5
      3.2. Problems with Error Responses and Already Executed Changes .9
      3.3. UAS Behavior ..............................................10
      3.4. UAC Behavior ..............................................11
      3.5. Glare Situations ..........................................11
      3.6. Example of UAS Behavior ...................................12
      3.7. Example of UAC Behavior ...................................14
      3.8. Clarifications on Canceling Re-INVITEs ....................17
   4. Refreshing a Dialog's Targets ..................................17
      4.1. Background and Terminology on a Dialog's Targets ..........17
      4.2. Background on Target-Refresh Requests .....................17
      4.3. Clarification on the Atomicity of Target-Refresh Requests .18
      4.4. UA Updating the Dialog's Local Target in a Request ........19
      4.5. UA Updating the Dialog's Local Target in a Response .......19
      4.6. A Request Updating the Dialog's Remote Target .............19
      4.7. A Response Updating the Dialog's Remote Target ............20
      4.8. Race Conditions and Target Refreshes ......................20
      4.9. Early Dialogs .............................................21
   5. A UA Losing Its Contact ........................................21
      5.1. Background on Re-INVITE Transaction Routing ...............22
      5.2. Problems with UAs Losing Their Contact ....................22
      5.3. UAS Losing Its Contact: UAC Behavior ......................22
      5.4. UAC Losing Its Contact: UAS Behavior ......................23
      5.5. UAC Losing Its Contact: UAC Behavior ......................24
   6. Security Considerations ........................................24
   7. Acknowledgements ...............................................24
   8. References .....................................................25
      8.1. Normative References ......................................25
      8.2. Informative References ....................................25

1. Introduction ๐ŸŒธ

okay so Section 14 of RFC 3261 [RFC3261] defines an INVITE request sent inside an existing dialog as a re-INVITE ๐Ÿ’… you use a re-INVITE to change session parameters, dialog parameters, or both. one re-INVITE can do both at once. for example, it can change the IP address where a media stream is received (session) and the remote target of the dialog (dialog). that remote-target part works because a re-INVITE is a target refresh request, as defined in Section 6 of RFC 3261 [RFC3261]. it's giving multitasking ๐Ÿงš

a re-INVITE transaction comes with an offer/answer [RFC3264] exchange attached. the UAC (User Agent Client) that sends a given re-INVITE can be the offerer or the answerer. if the UAC wants to be the offerer, it puts an offer in the re-INVITE, and the UAS (User Agent Server) answers in a response. if the UAC wants to be the answerer, it leaves the offer out of the re-INVITE. then the UAS gives an offer in its response to the re-INVITE, so the UAS ends up being the offerer. ๐Ÿฆ‹

certain transactions inside a re-INVITE, like UPDATE [RFC3311] transactions, can also have offer/answer exchanges. a UA (User Agent) can be the offerer or the answerer in any of those, no matter which role it had in the umbrella re-INVITE transaction. the roles are independent, bestie โœจ

implementors got confused about how a UAS should handle re-INVITEs. mostly they wanted to know which type of response a UAS should send in which situation. this doc clears that up ๐Ÿซถ

there was also confusion about target refresh requests, and re-INVITEs are only one kind of those. this doc explains how remote targets get refreshed too ๐Ÿ’œ

Indented passages such as this one are used in this document to provide additional information and clarifying text. They do not contain normative protocol behavior.

2. Terminology ๐Ÿ“

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119]. these are the BCP 14 key words, and they're the ones that carry the requirement weight, so read them carefully ๐Ÿ”ฅ

quick glossary:

  • UA: User Agent.
  • UAC: User Agent Client.
  • UAS: User Agent Server.
Note that the terms UAC and UAS are used with respect to an INVITE or re-INVITE transaction and do not necessarily reflect the role of the UA concerned with respect to any other transaction, such as an UPDATE transaction occurring within the INVITE transaction. so a UA can be a UAC in one transaction and a UAS in another, and that's totally fine ๐ŸŒˆ

3. Changing the Session State during a Re-INVITE ๐Ÿงš

the following sub-sections talk through how to change the state of the session during a re-INVITE transaction. more on that next, babe ๐Ÿ’–

3.1. Background on Re-INVITE Handling by UASs โœจ

okay so, eventually a UAS that gets a re-INVITE has to send back a response ๐Ÿ’… Some re-INVITEs can be answered right away because nobody has to click anything (like changing the IP address where a media stream is received). Other re-INVITEs need the user to weigh in first (like adding a video stream to an audio-only call), so those can't be answered immediately ๐Ÿ™ˆ

error responses to a re-INVITE have their own vibe. per Section 12.2.2 of RFC 3261 [RFC3261], if a re-INVITE gets rejected, no state changes happen. that covers state changes tied to the re-INVITE transaction and to all the other transactions inside it (this section is only about the session state; target refreshes are covered in Section 4.2). so the session state ends up exactly how it was before the re-INVITE showed up ๐Ÿฆ‹ Figure 1 shows this:

             UAC                                          UAS

              |                                            |
              |-------------(1) INVITE SDP1--------------->|
              |                                            |
              |<------------(2) 200 OK SDP2----------------|
              |                                            |
              |------------------(3) ACK------------------>|
              |                                            |
              |                                            |
              |-------------(4) INVITE SDP3--------------->|
              |                                            |
              |<-----------------(5) 4xx-------------------|
              |                                            |
              |------------------(6) ACK------------------>|
              |                                            |

Figure 1: Rejection of a re-INVITE

so the UAs do an offer/answer exchange to set up an audio-only session ๐ŸŽ€

     SDP1:
        m=audio 30000 RTP/AVP 0

     SDP2:
        m=audio 31000 RTP/AVP 0

later on, the UAC sends a re-INVITE (4) to add a video stream ๐ŸŒธ

     SDP3:
        m=audio 30000 RTP/AVP 0
        m=video 30002 RTP/AVP 31

the UAS is set up to automatically reject video streams, so it sends back an error response (5) ๐Ÿ’€ at that point the session is still running on the stuff from the first offer/answer, which is SDP1 and SDP2. again, the session state is the same as before the re-INVITE came in โœจ

in that last example, the UAS rejected every change in the re-INVITE by sending an error response. but sometimes a UAS wants to accept some of the changes and not others ๐Ÿงš in that case, the UAS sends a 200 (OK) response with a Session Description Protocol (SDP) that says which changes got accepted and which didn't. Figure 2 shows it:

             UAC                                          UAS

              |                                            |
              |-------------(1) INVITE SDP1--------------->|
              |                                            |
              |<------------(2) 200 OK SDP2----------------|
              |                                            |
              |------------------(3) ACK------------------>|
              |                                            |
              |                                            |
              |-------------(4) INVITE SDP3--------------->|
              |                                            |
              |<------------(5) 200 OK SDP4----------------|
              |                                            |
              |------------------(6) ACK------------------>|
              |                                            |

Figure 2: Automatic rejection of a video stream

the UAs do the offer/answer dance again for an audio-only session ๐Ÿฆ‹

     SDP1:
        m=audio 30000 RTP/AVP 0
        c=IN IP4 192.0.2.1

     SDP2:
        m=audio 31000 RTP/AVP 0
        c=IN IP4 192.0.2.5

then, later, the UAC switches to an access with higher bandwidth ๐Ÿš€ so it sends a re-INVITE (4) to change the IP address where it receives the audio stream to the new one, and to add a video stream too.

     SDP3:
        m=audio 30000 RTP/AVP 0
        c=IN IP4 192.0.2.2
        m=video 30002 RTP/AVP 31
        c=IN IP4 192.0.2.2

the UAS is automatically set to reject video streams, but it does need to accept the audio stream's new remote IP address. so it sends a 200 (OK) and sets the port of the video stream to zero in its SDP ๐Ÿซถ

     SDP4:
        m=audio 31000 RTP/AVP 0
        c=IN IP4 192.0.2.5
        m=video 0 RTP/AVP 31

in the previous example, the UAS was set to automatically reject added video streams. Figure 3 is for a UAS that needs its user to say yes or no to a new video stream. it also uses reliable provisional responses [RFC3262] (PRACK transactions aren't shown, to keep things clean) ๐ŸŒˆ

             UAC                                          UAS

              |                                            |
              |-------------(1) INVITE SDP1--------------->|
              |                                            |
              |<------------(2) 200 OK SDP2----------------|
              |                                            |
              |------------------(3) ACK------------------>|
              |                                            |
              |                                            |
              |-------------(4) INVITE SDP3--------------->|
              |                                            |
              |<----(5) 183 Session Progress SDP4----------|
              |                                            |
              |                                            |
              |<------------(6) UPDATE SDP5----------------|
              |                                            |
              |-------------(7) 200 OK SDP6--------------->|
              |                                            |
              |<---------------(8) 200 OK------------------|
              |                                            |
              |------------------(9) ACK------------------>|
              |                                            |

Figure 3: Manual rejection of a video stream by the user

everything up to (4) matches the last example. in (5), the UAS accepts the audio stream's new remote IP address but doesn't accept the video stream yet ๐Ÿ™ˆ instead of marking the stream 'inactive', it gives a null IP address, because inactive streams still have to exchange RTP Control Protocol (RTCP) traffic.

     SDP4:
        m=audio 31000 RTP/AVP 0
        c=IN IP4 192.0.2.5
        m=video 31002 RTP/AVP 31
        c=IN IP4 0.0.0.0

later, the UAS's user says no to the video stream. so the UAS sends an UPDATE request (6) that sets the video stream's port to zero in its offer ๐Ÿ˜ญ

     SDP5:
        m=audio 31000 RTP/AVP 0
        c=IN IP4 192.0.2.5
        m=video 0 RTP/AVP 31
        c=IN IP4 0.0.0.0

the UAC sends back a 200 (OK) to the UPDATE (7) with this answer:

     SDP6:
        m=audio 30000 RTP/AVP 0
        c=IN IP4 192.0.2.2
        m=video 0 RTP/AVP 31

and now the UAS sends a 200 (OK) (8) to the re-INVITE ๐Ÿ‘‘

in all the examples above, the UAC of the re-INVITE transaction was the offerer. examples where the UACs are the answerers would look pretty similar ๐Ÿ“

3.2. Problems with Error Responses and Already Executed Changes โœจ

Section 3.1 shows how a UAS can reject all the changes in a re-INVITE without running any of them, by sending an error response (Figure 1). it also shows how a UAS can run some of the changes and reject others by sending a 2xx response (Figures 2 and 3). a UAS can accept and reject different sets of changes at the same time (Figure 2), or at different times (Figure 3) ๐Ÿฆ‹

the part that confused implementors is this: a UAS gets a re-INVITE, runs some of the changes in it, and then wants to reject all of those already-run changes and go back to the pre-re-INVITE state ๐Ÿ˜ญ that UAS might think about sending an error response to the re-INVITE (the message flow would look like Figure 1), or using an UPDATE request to go back to the pre-re-INVITE state and then sending a 2xx response to the re-INVITE (the message flow would look like Figure 3). this section explains the problems with the error response option in that situation. to dodge those problems, the UAS should use the latter option (an UPDATE request plus a 2xx response). Sections 3.3 and 3.4 have the normative statements that help avoid these problems ๐Ÿ’œ

here's why an error response isn't the way to undo changes that already ran: an error response to a re-INVITE whose changes have already been executed (for example, because of UPDATE transactions or reliable provisional responses) is effectively asking for a change in the session state ๐Ÿ’€ but the UAC has no way to reject that change if it can't carry the changes out. in other words, if the UAC can't go back to the pre-re-INVITE state, it has no way to tell the UAS that's the case ๐Ÿฅบ

3.3. UAS Behavior โœจ

okay so, UASs should only send back an error response to a re-INVITE if NOTHING has been changed in the session state since the re-INVITE came in ๐Ÿ’… That error response basically says "nope, I didn't execute any changes from this re-INVITE or from any transaction inside it" ๐Ÿ™ˆ

if even ONE of the changes asked for in a re-INVITE (or in any transaction inside it) has already been carried out, the UAS SHOULD return a 2xx response ๐ŸŽ€

so when is a change to the session state considered executed? ๐Ÿค” It's when an offer/answer without preconditions [RFC4032] for the stream has finished successfully, OR when the UA has sent or received media using the new parameters ๐Ÿฆ‹ Connection establishment messages (like TCP SYN), connectivity checks (like the ones used with Interactive Connectivity Establishment (ICE) [RFC5245]), and any other messages used while working through the preconditions for a stream do NOT count as media ๐Ÿ™…โ€โ™€๏ธ

Normally, a UA receiving media can easily tell when the new parameters for the media stream are in use (e.g., media shows up on a new port) ๐ŸŒธ But in some scenarios, the UA has to actually process the incoming media packets to figure out whether they're using the old or the new parameters ๐Ÿง

ok the big difference here is between offer/answer with and without preconditions ๐Ÿซถ A successful offer/answer without preconditions means the new parameters for the media stream are already considered to be in use โœจ With preconditions, it's a different story ๐Ÿ‘€ When all the mandatory preconditions for the stream are met, that just means the new parameters are ready to be used ๐Ÿ’œ They won't actually be used until the UAS decides to use them ๐Ÿงš During session establishment, the UAS can wait before using the media parameters until the callee starts being alerted or until the callee accepts the session ๐Ÿ“ž During session modification, the UAS can wait until its user accepts the changes to the session ๐Ÿ™Œ When the UAS sends media more or less continuously, the UAC can notice the new parameters are in use because it receives media that uses them ๐Ÿ”ฅ But that trick doesn't work for other types of streams ๐Ÿ˜ญ

so, it is RECOMMENDED that when a UAS decides to start using the new parameters for a stream where all mandatory preconditions have been met, the UAS either sends media using the new parameters OR sends a new offer where the precondition-related attributes for the stream have been removed ๐Ÿ’– And again, a successful offer/answer without preconditions means the new parameters for the media stream are already considered to be in use ๐ŸŒˆ


3.4. UAC Behavior ๐ŸŽ€

a UAC that gets an error response to a re-INVITE which undoes changes already executed within that re-INVITE might be dealing with a legacy UAS that doesn't support this spec (aka a UAS that doesn't follow the guidelines in Section 3.3) ๐Ÿ™ˆ There are also some race condition situations that knock both user agents out of sync ๐Ÿ˜ตโ€๐Ÿ’ซ To handle those, a UAC that gets an error response to a re-INVITE for which changes have already been executed SHOULD generate a new re-INVITE or UPDATE request so both UAs have a common view of the session state โœจ (the UAC uses the criteria in Section 3.3 to decide whether changes were executed for a particular stream) ๐Ÿง  The point of this new offer/answer exchange is to synchronize both UAs, NOT to request changes the UAS might reject ๐Ÿšซ So session parameters in the offer/answer exchange SHOULD be as close as possible to those in the pre-re-INVITE state ๐Ÿ’…


3.5. Glare Situations ๐Ÿ’œ

okay glare, so Section 4 of RFC 3264 [RFC3264] defines glare as a user agent receiving an offer after it sent one but BEFORE it received an answer ๐Ÿซฃ That section has rules to avoid glare in most cases ๐Ÿ™Œ But when a glare still happens anyway (because of a race condition), it's handled the way Sections 14.1 and 14.2 of RFC 3261 [RFC3261] say ๐Ÿ’ซ The UAS returns a 491 (Request Pending) response, and the UAC retries the offer after a randomly selected time, which depends on which user agent owns the Call-ID of the dialog ๐ŸŽฒ The rules in RFC 3261 [RFC3261] cover more than just collisions between re-INVITEs that contain offers ๐Ÿฆ‹ They cover collisions between ANY two re-INVITEs, even ones without offers ๐ŸŒธ Sections 5.2 and 5.3 of RFC 3311 [RFC3311] extend those rules to also cover collisions between an UPDATE request carrying an offer and another message (UPDATE, PRACK, or INVITE) also carrying an offer ๐Ÿ”ฅ

the rules in RFC 3261 [RFC3261] do NOT cover collisions between an UPDATE request and a non-2xx final response to a re-INVITE ๐Ÿ™ƒ Since both could be asking for changes to the session state, it wouldn't be clear which changes to run first ๐Ÿ˜ฌ BUT the procedures from Section 3.4 already cover this kind of situation ๐Ÿซถ So there's no need to specify further rules here ๐Ÿ“


3.6. Example of UAS Behavior ๐Ÿงš

this section has an example of a UAS implementing this spec, using an UPDATE request and a 2xx response to a re-INVITE to go back to the pre-re-INVITE state ๐Ÿ’– In the example (Figure 4), the UAS needs its user's input to accept or reject adding a video stream, and it uses reliable provisional responses [RFC3262] (PRACK transactions aren't shown, for clarity) โœจ

             UAC                                          UAS

              |                                            |
              |-------------(1) INVITE SDP1--------------->|
              |                                            |
              |<------------(2) 200 OK SDP2----------------|
              |                                            |
              |------------------(3) ACK------------------>|
              |                                            |
              |                                            |
              |-------------(4) INVITE SDP3--------------->|
              |                                            |
              |<----(5) 183 Session Progress SDP4----------|
              |                                            |
              |-------------(6) UPDATE SDP5--------------->|
              |                                            |
              |<------------(7) 200 OK SDP6----------------|
              |                                            |
              |                                            |
              |<------------(8) UPDATE SDP7----------------|
              |                                            |
              |-------------(9) 200 OK SDP8--------------->|
              |                                            |
              |<--------------(10) 200 OK------------------|
              |                                            |
              |-----------------(11) ACK------------------>|
              |                                            |

Figure 4: Rejection of a video stream by the user

first up, the two UAs do an offer/answer exchange to set up an audio-only session ๐ŸŽง

SDP1:
   m=audio 30000 RTP/AVP 0
   c=IN IP4 192.0.2.1

SDP2:
   m=audio 31000 RTP/AVP 0
   c=IN IP4 192.0.2.5

later on, the UAC sends a re-INVITE (4) to add a new codec to the audio stream AND add a video stream to the session ๐ŸŽฌ

SDP3:
   m=audio 30000 RTP/AVP 0 3
   c=IN IP4 192.0.2.1
   m=video 30002 RTP/AVP 31
   c=IN IP4 192.0.2.1

in (5), the UAS accepts the audio codec addition but doesn't accept the video stream yet ๐Ÿ™… Instead of setting the stream to 'inactive', it gives a null IP address, because inactive streams still need to exchange RTCP traffic ๐Ÿ“ก

SDP4:
   m=audio 31000 RTP/AVP 0 3
   c=IN IP4 192.0.2.5
   m=video 31002 RTP/AVP 31
   c=IN IP4 0.0.0.0

later again, the UAC sends an UPDATE request (6) to remove the original audio codec from the audio stream (the UAC could also have used the PRACK to (5) to ask for this change) ๐Ÿ™Œ

SDP5:
   m=audio 30000 RTP/AVP 3
   c=IN IP4 192.0.2.1
   m=video 30002 RTP/AVP 31
   c=IN IP4 192.0.2.1

SDP6:
   m=audio 31000 RTP/AVP 3
   c=IN IP4 192.0.2.5
   m=video 31002 RTP/AVP 31
   c=IN IP4 0.0.0.0

and then, at a later point, the UAS's user rejects adding the video stream ๐Ÿ’€ The UAS also decides to go back to the original audio codec ๐Ÿ”„ So the UAS sends an UPDATE request (8) that sets the port of the video stream to zero and offers the original audio codec in its SDP ๐Ÿ˜ค

SDP7:
   m=audio 31000 RTP/AVP 0
   c=IN IP4 192.0.2.5
   m=video 0 RTP/AVP 31
   c=IN IP4 0.0.0.0

the UAC accepts the audio codec change in its 200 (OK) response (9) to the UPDATE request โœ…

SDP8:
   m=audio 30000 RTP/AVP 0
   c=IN IP4 192.0.2.1
   m=video 0 RTP/AVP 31
   c=IN IP4 192.0.2.1

and now the UAS sends its 200 (OK) response (10) to the re-INVITE ๐ŸŽ‰ Notice that the media state after this 200 (OK) response is the SAME as the pre-re-INVITE media state ๐Ÿซง

3.7. Example of UAC Behavior ๐ŸŽ€

Okay bestie, Figure 5 is a race condition situation, and it's SO good because the UAs end up with totally different views of the session ๐Ÿ˜ญ๐Ÿ’…

  a:sendrecv                                                  a:sendrecv
  v:inactive                                                  v:inactive

             UA1                   Proxy                   UA2

              |                      |                      |
              |----(1) INVITE SDP1-->|                      |
              |                      |----(2) INVITE SDP1-->|
              |                      |                      |
              |                      |<----(3) 183 SDP2-----| a:sendrecv
  a:sendrecv  |<----(4) 183 SDP2-----|                      | v:recvonly
  v:sendonly  |                      |                      |
              |                      |<------(5) 4xx -------|
              |                      |-------(6) ACK ------>| a:sendrecv
              |           +-(7) 4xx -|                      | v:inactive
              |           |          |<---(8) UPDATE SDP3---|
              |<---(9) UPDATE SDP3---|                      |
              |           |          |                      |
  a:sendonly  |---(10) 200 OK SDP4-->|                      |
  v:inactive  |           |          |---(11) 200 OK SDP4-->| a:recvonly
              |<-(7) 4xx -+          |                      | v:inactive
  a:sendrecv  |------(12) ACK ------>|                      |
  v:inactive  |                      |                      |

                       a: status of the audio stream
                       v: status of the video stream

                Figure 5: Message flow with race condition

The UAs in Figure 5 are in a session that, right before the messages in the figure start, has a sendrecv audio stream and an inactive video stream. UA1 sends a re-INVITE (1) asking to make the video stream sendrecv. ๐Ÿฆ‹

SDP1:
   m=audio 20000 RTP/AVP 0
   a=sendrecv
   m=video 20002 RTP/AVP 31
   a=sendrecv

UA2 is set up to automatically accept incoming video streams, but it asks the user for input before it generates an outgoing video stream. So UAS2 makes the video stream recvonly by returning a 183 (Session Progress) response (2). ๐ŸŒธ

SDP2:
   m=audio 30000 RTP/AVP 0
   a=sendrecv
   m=video 30002 RTP/AVP 31
   a=recvonly

When it's time for input, UA2's user chooses to have neither incoming nor outgoing video. To make the video stream inactive, UA2 returns a 4xx error response (5) to the re-INVITE. The ACK request (6) for this error response is generated by the proxy between both user agents. Note that this error response undoes already executed changes. So UA2 is a legacy UA that does not support this specification. ๐Ÿ’€

The proxy relays the 4xx response (7) toward UA1. But the 4xx response (7) takes its sweet time getting to UA1 (for example, the response may have been sent over UDP and the first few retransmissions got lost). Meanwhile, UA2's user decides to put the audio stream on hold. UA2 sends an UPDATE request (8) that makes the audio stream recvonly. The video stream is inactive, so it isn't modified and stays inactive. ๐Ÿ™ˆ

SDP3:
   m=audio 30000 RTP/AVP 0
   a=recvonly
   m=video 30002 RTP/AVP 31
   a=inactive

The proxy relays the UPDATE request (9) to UA1. This UPDATE request (9) arrives at UA1 before the 4xx response (7) that was sent earlier. UA1 accepts the changes in the UPDATE request and returns a 200 (OK) response (10) to it. โœจ

SDP4:
   m=audio 20000 RTP/AVP 0
   a=sendonly
   m=video 30002 RTP/AVP 31
   a=inactive

Later on, the 4xx response (7) finally shows up at UA1. This response makes the session return to its pre-re-INVITE state. So for UA1, the audio stream is sendrecv and the video stream is inactive. But for UA2, the audio stream is recvonly (and the video stream is also inactive). Two different realities, bestie, not it ๐Ÿ˜ญ

After the message flow in Figure 5, if you follow the recommendations in this section, then when UA1 received an error response (7) that undid already executed changes, UA1 would generate an UPDATE request with an SDP reflecting the pre-re-INVITE state (that is, sendrecv audio and inactive video). UA2 could then return a 200 (OK) response to that UPDATE request, making the audio stream recvonly, which is the state UA2's user had asked for. Such an UPDATE transaction would get the UAs back into sync ๐Ÿซถ๐ŸŒˆ

3.8. Clarifications on Canceling Re-INVITEs ๐Ÿ’œ

Section 9.2 of RFC 3261 [RFC3261] specifies how a UAS behaves when it responds to a CANCEL request. Such a UAS responds to the INVITE request with a 487 (Request Terminated) at the SHOULD level. Per the rules in Section 3.3, if the INVITE request was a re-INVITE and some of its requested changes had already been executed, the UAS would return a 2xx response instead ๐Ÿ‘€

4. Refreshing a Dialog's Targets ๐Ÿฆ‹

The following sections discuss how to refresh the targets of a dialog. Let's go!! ๐Ÿ’–

4.1. Background and Terminology on a Dialog's Targets

As described in Section 12 of RFC 3261 [RFC3261], a UA involved in a dialog keeps a record of the SIP or Session Initiation Protocol Secure (SIPS) URI where it can talk to one specific instance of its peer. This is called the "dialog's remote target URI," and it's equal to the URI contained in the Contact header of requests and responses it receives from the peer. This document introduces the complementary concept of the "dialog's local target URI," which is a UA's record of the SIP or SIPS URI where the peer can talk to it. It's equal to the URI contained in the Contact header of requests and responses it sends to the peer. These terms are complementary because the "dialog's remote target URI" according to one UA is the "dialog's local target URI" according to the other UA, and vice versa. Two sides of the same coin, iykyk ๐Ÿช™๐Ÿ’œ

4.2. Background on Target-Refresh Requests

A target-refresh request is defined as follows in Section 6 of RFC 3261 [RFC3261]:

A target-refresh request sent within a dialog is defined as a request that can modify the remote target of the dialog.

Additionally, 2xx responses to target-refresh requests can also update the remote target of the dialog. As discussed in Section 12.2 of RFC 3261 [RFC3261], re-INVITEs are target-refresh requests. ๐Ÿ”ฅ

RFC 3261 [RFC3261] specifies the behavior of UASs receiving target-refresh requests, and of UACs receiving a 2xx response to a target-refresh request.

Section 12.2.2 of RFC 3261 [RFC3261] says:

When a UAS receives a target refresh request, it MUST replace the dialog's remote target URI with the URI from the Contact header field in that request, if present.

Section 12.2.1.2 of RFC 3261 [RFC3261] says:

When a UAC receives a 2xx response to a target refresh request, it MUST replace the dialog's remote target URI with the URI from the Contact header field in that response, if present.

The fact that re-INVITEs can be long-lived transactions, and can have other transactions inside them, makes it necessary to revise these rules. Section 4.3 specifies new rules for handling target-refresh requests. Note that the new rules apply to any target-refresh request, not only to re-INVITEs. โญ

4.3. Clarification on the Atomicity of Target-Refresh Requests

The local and remote targets of a dialog are a special kind of state information, because they play an essential role in how SIP messages get exchanged between UAs in a dialog. A UA involved in a dialog receives the remote target of the dialog from the remote UA, and it uses that received remote target to send SIP requests to the remote UA. ๐Ÿงš

The dialog's local target is a piece of state information that is not meant to be negotiated. When a UA changes its local target (that is, the UA changes its IP address), the UA simply tells the remote UA about its new local target. For example, the UA tells the remote UA its new IP address so it can stay reachable. UAs need to follow the behavior specified in Sections 4.4, 4.5, 4.6, and 4.7 of this specification instead of the behavior specified in RFC 3261 [RFC3261], which was discussed in Section 4.2. The new behavior regarding target-refresh requests means that a target-refresh request can, in some cases, update the remote target even if the request gets a final error response. This means that target-refresh requests are not atomic ๐Ÿซ 

4.4. UA Updating the Dialog's Local Target in a Request

In order to update its local target, a UA can send a target-refresh request. If the UA receives an error response to the target-refresh request, the remote UA has not updated its remote target.

This allows UASs to authenticate target-refresh requests (see Section 26.2 of RFC 3261 [RFC3261]).

If the UA receives a reliable provisional response or a 2xx response to the target-refresh request, or the UA receives an in-dialog request on the new local target, the remote UA has updated its remote target. The UA can consider the target refresh operation completed. โœ…

Even if the target request was a re-INVITE and the final response to the re-INVITE was an error response, the UAS would not revert to the pre-re-INVITE remote target.

A UA SHOULD NOT use the same target refresh request to refresh the target and to make session changes, unless the session changes can be trivially accepted by the remote UA (for example, an IP address change). Piggybacking a target refresh with more complicated session changes would make it unnecessarily complicated for the remote UA to accept the target refresh while rejecting the session changes. Only in the case where the target refresh request is a re-INVITE and the UAS supports reliable provisional responses or UPDATE requests, the UAC MAY piggyback session changes and a target refresh in the same re-INVITE. ๐Ÿ“

4.5. UA Updating the Dialog's Local Target in a Response

A UA processing an incoming target refresh request can update its local target by returning a reliable provisional response or a 2xx response to the target-refresh request. The response needs to contain the updated local target URI in its Contact header field. Once the response is sent, the UA can consider the target refresh operation completed. ๐ŸŽ€

4.6. A Request Updating the Dialog's Remote Target ๐Ÿ’–

okay so this part is about what a UA does after it gets a target-refresh request that updates the remote target ๐ŸŽ€

If the UA receives a target-refresh request that has been properly authenticated (see Section 26.2 of RFC 3261 [RFC3261]), the UA SHOULD generate a reliable provisional response or a 2xx response to the target-refresh request. If generating those responses isn't possible (e.g., the UA doesn't support reliable provisional responses and needs user input before generating a final response), the UA SHOULD send an in-dialog request to the remote UA using the new remote target. If the UA doesn't need to send a request for other reasons, the UAS can send an UPDATE request. Once it sends a reliable provisional response or a 2xx response to the target-refresh request, or a request to the new remote target, the UA MUST replace the dialog's remote target URI with the URI from the Contact header field in the target-refresh request. ๐Ÿฆ‹

Reliable provisional responses in SIP are specified in RFC 3262 [RFC3262]. In this document, reliable provisional responses are those that use the mechanism defined in RFC 3262 [RFC3262]. Other specifications may define ways to send provisional responses reliably using non-SIP mechanisms (e.g., using media-level messages to acknowledge the reception of the SIP response). For the purposes of this document, provisional responses using those non-SIP mechanisms are considered unreliable responses. Note that non-100 provisional responses are only applicable to INVITE transactions [RFC4320].

If the UA, instead of sending a reliable provisional response or a 2xx response to the target-refresh request, or a request to the new target, generates an error response to the target-refresh request, the UA MUST NOT update its dialog's remote target. ๐Ÿ™…โ€โ™€๏ธ

4.7. A Response Updating the Dialog's Remote Target ๐ŸŒธ

if a UA gets a reliable provisional response or a 2xx response to a target-refresh request, the UA MUST replace the dialog's remote target URI with the URI from the Contact header field in that response, if one is present. โœจ

If a UA gets an unreliable provisional response to a target-refresh request, the UA MUST NOT refresh the dialog's remote target. no refresh for you ๐Ÿ’…

4.8. Race Conditions and Target Refreshes ๐ŸŽ๏ธ

SIP does request ordering with the Cseq header field. So a UA that gets two requests at roughly the same time can tell which one is newer. ๐Ÿ‘€ But SIP does not order responses against requests. For example, if a UA gets a 200 (OK) response to an UPDATE request and an UPDATE request at roughly the same time, it can't tell which one was sent last. Both of them can refresh the remote target, so the UA needs to know which message was sent last to figure out which remote target to use. this is the messy part ๐Ÿ˜ญ

This document sets up the following rule to dodge that situation. If the protocol lets a UA use a target-refresh request at the moment the UA wants to refresh its local target, the UA MUST use a target-refresh request instead of a response to refresh its local target. ๐Ÿซถ That means a UA only uses a response (i.e., a reliable provisional response or a 2xx response to a target-refresh request) to refresh its local target when it can't use a target-refresh request at that point in time (e.g., the UAS of an ongoing re-INVITE that doesn't support UPDATE). โœจ

4.9. Early Dialogs ๐Ÿงš

the rules in this section about which messages can refresh a dialog's target also apply to early dialogs created by an initial INVITE transaction. Also, as Section 13.2.2.4 of RFC 3261 [RFC3261] says, when the UAC gets a 2xx response to the initial INVITE, it recomputes the whole route set of the dialog, and the dialog moves from the "early" state to the "confirmed" state. ๐ŸŽ€

Section 12.1 of RFC 3261 allows unreliable provisional responses to create early dialogs. However, per the rules in this section, unreliable provisional responses can't refresh the target of a dialog. So the UAC of an initial INVITE transaction won't do any target refresh when it gets an unreliable provisional response with an updated Contact value on an (already established) early dialog. ๐Ÿ™ˆ Also, a given UAS can set up additional early dialogs, which can have different targets, by returning additional unreliable provisional responses with different To tags. ๐ŸŒˆ

5. A UA Losing Its Contact ๐Ÿฆ‹

The following sections cover the case where a UA loses its transport address during an ongoing re-INVITE transaction. A UA like that will refresh the dialog's local target so it reflects its new transport address. ๐Ÿงณ Target refreshes that don't involve changes to the UA's transport address are outside the scope of this section. Also, UAs that lose their transport address during a non-re-INVITE transaction (e.g., a UA losing its transport address right after sending an UPDATE request but before getting a response to it) are out of scope too. ๐Ÿ™…โ€โ™€๏ธ

The rules in this section also apply to initial INVITE requests that have established early dialogs. ๐Ÿ’œ

5.1. Background on Re-INVITE Transaction Routing ๐Ÿ—บ๏ธ

Re-INVITEs are routed using the dialog's route set, which contains all the proxy servers that have to be traversed by requests sent within the dialog. Responses to the re-INVITE are routed using the Via entries in the re-INVITE. ๐Ÿ“ฎ

ACK requests for 2xx responses and for non-2xx final responses are generated in different ways, bestie. As Sections 14.1 and 13.2.1 of RFC 3261 [RFC3261] say, ACK requests for 2xx responses are generated by the UAC core and routed using the dialog's route set. As Section 17.1.1.2 of RFC 3261 [RFC3261] says, ACK requests for non-2xx final responses are generated by the INVITE client transaction (so they're generated hop-by-hop by the proxy servers on the path) and sent to the same transport address as the re-INVITE. ๐ŸŒธ

5.2. Problems with UAs Losing Their Contact ๐Ÿ˜ฌ

Refreshing the dialog's remote target during a re-INVITE transaction (see Section 4.3) causes some issues because re-INVITE transactions can be long-lived. As described in Section 5.1, the way responses to the re-INVITE and ACKs for non-2xx final responses get routed is fixed once the re-INVITE is sent. The routing of these messages doesn't depend on the dialog's route set, so target refreshes within an ongoing re-INVITE don't affect their routing. A UA that changes its location (i.e., performs a target refresh) but is still reachable at its old location will still be able to receive those messages, since they get sent to the old location. However, a UA that can't be reached at its old location anymore won't be able to receive them. ๐Ÿ’”

The following sections describe the errors UAs run into when they lose their transport address during a re-INVITE. When UAs detect some of these errors, UAs following the rules in RFC 3261 [RFC3261] will terminate the dialog. Once the dialog is terminated, the only option for the UAs is to establish a new dialog. The following sections change the requirements RFC 3261 [RFC3261] places on UAs when certain errors occur, so the UAs can recover from those errors. In short, the UAs generate a new re-INVITE transaction to synchronize both UAs. ๐Ÿ”„ Note that there are existing UA implementations already deployed that already implement this behavior. ๐Ÿ™Œ

5.3. UAS Losing Its Contact: UAC Behavior ๐Ÿงฉ

When a UAS moves to a new contact and loses its old contact, and then generates a non-2xx final response to the re-INVITE, it won't be able to receive the ACK request. The entity that gets the response (and so generates the ACK request) will get either a transport error or a timeout error. As described in Section 8.1.3.1 of RFC 3261 [RFC3261], those get treated as a 503 (Service Unavailable) response and a 408 (Request Timeout) response, respectively. If the sender of the ACK request is a proxy server, it will typically ignore this error. If the sender of the ACK request is the UAC, then according to Section 12.2.1.2 of RFC 3261 [RFC3261], it is supposed to (at the SHOULD level) terminate the dialog by sending a BYE request. However, because of the special properties of ACK requests for non-2xx final responses, most existing UACs don't terminate the dialog when an ACK request fails, which is honestly a good thing. ๐Ÿ€

A UAC that accepts a target refresh within a re-INVITE MUST ignore transport and timeout errors when generating an ACK request for a non-2xx final response. On top of that, the UAC SHOULD generate a new re-INVITE so both UAs have a common view of the state of the session. ๐Ÿซถ

It is possible that the errors ignored by the UAC weren't related to the target refresh operation. If that was the case, the second re-INVITE would fail and the UAC would terminate the dialog, because per the rules above, UACs only ignore errors when they accept a target refresh within the re-INVITE. ๐Ÿ™ˆ

5.4. UAC Losing Its Contact: UAS Behavior ๐Ÿซฃ

When a UAC moves to a new contact and loses its old contact, it won't be able to receive responses to the re-INVITE. So it'll never generate an ACK request. ๐Ÿ’€

As described in Section 16.9 of RFC 3261 [RFC3261], a proxy server that gets an error when forwarding a response doesn't take any measures. So proxy servers relaying responses basically ignore the error. ๐Ÿคทโ€โ™€๏ธ

If there are no proxy servers in the dialog's route set, the UAS will get an error when sending a non-2xx final response. The UAS core gets notified of the transaction failure, as described in Section 17.2.1 of RFC 3261 [RFC3261]. Most existing UASs don't terminate the dialog when they hit this failure, which is a relief. ๐Ÿฅน

No matter whether there are proxy servers in the dialog's route set, a UAS that generates a 2xx response to the re-INVITE will never get an ACK request for it. According to Section 14.2 of RFC 3261 [RFC3261], a UAS like that is supposed to (at the "should" level) terminate the dialog by sending a BYE request. ๐Ÿ“ž

A UAS that accepts a target refresh within a re-INVITE and never gets an ACK request after sending a final response to the re-INVITE SHOULD NOT terminate the dialog if the UA has received a new re-INVITE with a higher CSeq sequence number than the original one. ๐ŸŒŸ

5.5. UAC Losing Its Contact: UAC Behavior ๐ŸŒท

When a UAC moves to a new contact and loses its old contact, it won't be able to receive responses to the re-INVITE. So it'll never generate an ACK request. ๐Ÿ˜ตโ€๐Ÿ’ซ

Such a UAC SHOULD generate a CANCEL request to cancel the re-INVITE and cause the INVITE client transaction corresponding to the re-INVITE to enter the "Terminated" state. The UAC SHOULD also send a new re-INVITE so both UAs have a common view of the state of the session. โœจ

Per Section 14.2 of RFC 3261 [RFC3261], the UAS will accept new incoming re-INVITEs as soon as it has generated a final response to the previous INVITE request, which had a lower CSeq sequence number. ๐Ÿง 

6. Security Considerations ๐Ÿ”

okay bestie, this one's a chill-but-important section ๐Ÿ’… this doc doesn't introduce any new security issue โœจ it just clarifies how certain transactions should be handled in SIP. the security stuff for re-INVITEs and UPDATE requests is already covered in RFC 3261 [RFC3261] and RFC 3311 [RFC3311] ๐ŸŽ€

so here's the main vibe ๐Ÿฆ‹: in order not to reduce the security level for a given session, re-INVITEs and UPDATE requests SHOULD be secured using a mechanism equivalent to or stronger than the initial INVITE request that created the session ๐Ÿ”ฅ like, if the original INVITE was end-to-end integrity protected or encrypted, the later re-INVITEs and UPDATE requests should also be so ๐Ÿซถ don't let your session get less protected halfway through, it's giving insecure plot twist ๐Ÿ’€

7. Acknowledgements ๐ŸŒธ

big thank you to Paul Kyzivat ๐Ÿซถ who provided useful ideas on the topics discussed in this document ๐Ÿ’œ

8. References ๐Ÿ“š

8.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[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.

[RFC3262]  Rosenberg, J. and H. Schulzrinne, "Reliability of
           Provisional Responses in Session Initiation Protocol
           (SIP)", RFC 3262, June 2002.

[RFC3264]  Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model
           with Session Description Protocol (SDP)", RFC 3264,
           June 2002.

[RFC3311]  Rosenberg, J., "The Session Initiation Protocol (SIP)
           UPDATE Method", RFC 3311, October 2002.

[RFC4032]  Camarillo, G. and P. Kyzivat, "Update to the Session
           Initiation Protocol (SIP) Preconditions Framework",
           RFC 4032, March 2005.

8.2. Informative References

[RFC4320]  Sparks, R., "Actions Addressing Identified Issues with the
           Session Initiation Protocol's (SIP) Non-INVITE
           Transaction", RFC 4320, January 2006.

[RFC5245]  Rosenberg, J., "Interactive Connectivity Establishment
           (ICE): A Protocol for Network Address Translator (NAT)
           Traversal for Offer/Answer Protocols", RFC 5245,
           April 2010.

Authors' Addresses ๐Ÿงš

these are the people who wrote it, so you know who to thank (or DM) โœจ

Gonzalo Camarillo (editor)
Ericsson
Hirsalantie 11
Jorvas  02420
Finland

EMail: Gonzalo.Camarillo@ericsson.com


Christer Holmberg
Ericsson
Hirsalantie 11
Jorvas  02420
Finland

EMail: Christer.Holmberg@ericsson.com


Yang Gao
ZTE
China

EMail: gao.yang2@zte.com.cn
๐Ÿ“ฆ where this page comes from