tech-invite   World Map     

3GPP     Specs     Glossaries     Architecture     IMS     UICC       IETF     RFCs     Groups     SIP     ABNFs       Search

RFC 3261

 
 
 

SIP: Session Initiation Protocol

Part 6 of 13, p. 91 to 122
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 91 
16 Proxy Behavior

16.1 Overview

   SIP proxies are elements that route SIP requests to user agent
   servers and SIP responses to user agent clients.  A request may
   traverse several proxies on its way to a UAS.  Each will make routing
   decisions, modifying the request before forwarding it to the next
   element.  Responses will route through the same set of proxies
   traversed by the request in the reverse order.

   Being a proxy is a logical role for a SIP element.  When a request
   arrives, an element that can play the role of a proxy first decides
   if it needs to respond to the request on its own.  For instance, the
   request may be malformed or the element may need credentials from the
   client before acting as a proxy.  The element MAY respond with any

Top      Up      ToC       Page 92 
   appropriate error code.  When responding directly to a request, the
   element is playing the role of a UAS and MUST behave as described in
   Section 8.2.

   A proxy can operate in either a stateful or stateless mode for each
   new request.  When stateless, a proxy acts as a simple forwarding
   element.  It forwards each request downstream to a single element
   determined by making a targeting and routing decision based on the
   request.  It simply forwards every response it receives upstream.  A
   stateless proxy discards information about a message once the message
   has been forwarded.  A stateful proxy remembers information
   (specifically, transaction state) about each incoming request and any
   requests it sends as a result of processing the incoming request.  It
   uses this information to affect the processing of future messages
   associated with that request.  A stateful proxy MAY choose to "fork"
   a request, routing it to multiple destinations.  Any request that is
   forwarded to more than one location MUST be handled statefully.

   In some circumstances, a proxy MAY forward requests using stateful
   transports (such as TCP) without being transaction-stateful.  For
   instance, a proxy MAY forward a request from one TCP connection to
   another transaction statelessly as long as it places enough
   information in the message to be able to forward the response down
   the same connection the request arrived on.  Requests forwarded
   between different types of transports where the proxy's TU must take
   an active role in ensuring reliable delivery on one of the transports
   MUST be forwarded transaction statefully.

   A stateful proxy MAY transition to stateless operation at any time
   during the processing of a request, so long as it did not do anything
   that would otherwise prevent it from being stateless initially
   (forking, for example, or generation of a 100 response).  When
   performing such a transition, all state is simply discarded.  The
   proxy SHOULD NOT initiate a CANCEL request.

   Much of the processing involved when acting statelessly or statefully
   for a request is identical.  The next several subsections are written
   from the point of view of a stateful proxy.  The last section calls
   out those places where a stateless proxy behaves differently.

16.2 Stateful Proxy

   When stateful, a proxy is purely a SIP transaction processing engine.
   Its behavior is modeled here in terms of the server and client
   transactions defined in Section 17.  A stateful proxy has a server
   transaction associated with one or more client transactions by a
   higher layer proxy processing component (see figure 3), known as a
   proxy core.  An incoming request is processed by a server

Top      Up      ToC       Page 93 
   transaction.  Requests from the server transaction are passed to a
   proxy core.  The proxy core determines where to route the request,
   choosing one or more next-hop locations.  An outgoing request for
   each next-hop location is processed by its own associated client
   transaction.  The proxy core collects the responses from the client
   transactions and uses them to send responses to the server
   transaction.

   A stateful proxy creates a new server transaction for each new
   request received.  Any retransmissions of the request will then be
   handled by that server transaction per Section 17.  The proxy core
   MUST behave as a UAS with respect to sending an immediate provisional
   on that server transaction (such as 100 Trying) as described in
   Section 8.2.6.  Thus, a stateful proxy SHOULD NOT generate 100
   (Trying) responses to non-INVITE requests.

   This is a model of proxy behavior, not of software.  An
   implementation is free to take any approach that replicates the
   external behavior this model defines.

   For all new requests, including any with unknown methods, an element
   intending to proxy the request MUST:

      1. Validate the request (Section 16.3)

      2. Preprocess routing information (Section 16.4)

      3. Determine target(s) for the request (Section 16.5)

            +--------------------+
            |                    | +---+
            |                    | | C |
            |                    | | T |
            |                    | +---+
      +---+ |       Proxy        | +---+   CT = Client Transaction
      | S | |  "Higher" Layer    | | C |
      | T | |                    | | T |   ST = Server Transaction
      +---+ |                    | +---+
            |                    | +---+
            |                    | | C |
            |                    | | T |
            |                    | +---+
            +--------------------+

               Figure 3: Stateful Proxy Model

Top      Up      ToC       Page 94 
      4. Forward the request to each target (Section 16.6)

      5. Process all responses (Section 16.7)

16.3 Request Validation

   Before an element can proxy a request, it MUST verify the message's
   validity.  A valid message must pass the following checks:

      1. Reasonable Syntax

      2. URI scheme

      3. Max-Forwards

      4. (Optional) Loop Detection

      5. Proxy-Require

      6. Proxy-Authorization

   If any of these checks fail, the element MUST behave as a user agent
   server (see Section 8.2) and respond with an error code.

   Notice that a proxy is not required to detect merged requests and
   MUST NOT treat merged requests as an error condition.  The endpoints
   receiving the requests will resolve the merge as described in Section
   8.2.2.2.

   1. Reasonable syntax check

      The request MUST be well-formed enough to be handled with a server
      transaction.  Any components involved in the remainder of these
      Request Validation steps or the Request Forwarding section MUST be
      well-formed.  Any other components, well-formed or not, SHOULD be
      ignored and remain unchanged when the message is forwarded.  For
      instance, an element would not reject a request because of a
      malformed Date header field.  Likewise, a proxy would not remove a
      malformed Date header field before forwarding a request.

      This protocol is designed to be extended.  Future extensions may
      define new methods and header fields at any time.  An element MUST
      NOT refuse to proxy a request because it contains a method or
      header field it does not know about.

Top      Up      ToC       Page 95

Updated by:  RFC 5393/4.2.2 
   2. URI scheme check

      If the Request-URI has a URI whose scheme is not understood by the
      proxy, the proxy SHOULD reject the request with a 416 (Unsupported
      URI Scheme) response.

   3. Max-Forwards check

      The Max-Forwards header field (Section 20.22) is used to limit the
      number of elements a SIP request can traverse.

      If the request does not contain a Max-Forwards header field, this
      check is passed.

      If the request contains a Max-Forwards header field with a field
      value greater than zero, the check is passed.

      If the request contains a Max-Forwards header field with a field
      value of zero (0), the element MUST NOT forward the request.  If
      the request was for OPTIONS, the element MAY act as the final
      recipient and respond per Section 11.  Otherwise, the element MUST
      return a 483 (Too many hops) response.

   4. Optional Loop Detection check

      An element MAY check for forwarding loops before forwarding a
      request.  If the request contains a Via header field with a sent-
      by value that equals a value placed into previous requests by the
      proxy, the request has been forwarded by this element before.  The
      request has either looped or is legitimately spiraling through the
      element.  To determine if the request has looped, the element MAY
      perform the branch parameter calculation described in Step 8 of
      Section 16.6 on this message and compare it to the parameter
      received in that Via header field.  If the parameters match, the
      request has looped.  If they differ, the request is spiraling, and
      processing continues.  If a loop is detected, the element MAY
      return a 482 (Loop Detected) response.
   4.  Loop-Detection Check

   Proxies required to perform loop detection by RFC 5393 MUST perform
   the following loop-detection test before forwarding a request.  Each
   Via header field value in the request whose sent-by value matches a
   value placed into previous requests by this proxy MUST be inspected
   for the "second part" defined in Section 4.2.1 of RFC 5393.  This
   second part will not be present if the message was not forked when
   that Via header field value was added.  If the second field is
   present, the proxy MUST perform the second-part calculation described
   in Section 4.2.1 of RFC 5393 on this request and compare the result
   to the value from the Via header field.  If these values are equal,
   the request has looped and the proxy MUST reject the request with a
   482 (Loop Detected) response.  If the values differ, the request is
   spiraling and processing continues to the next step.
   5. Proxy-Require check

      Future extensions to this protocol may introduce features that
      require special handling by proxies.  Endpoints will include a
      Proxy-Require header field in requests that use these features,
      telling the proxy not to process the request unless the feature is
      understood.

Top      Up      ToC       Page 96 
      If the request contains a Proxy-Require header field (Section
      20.29) with one or more option-tags this element does not
      understand, the element MUST return a 420 (Bad Extension)
      response.  The response MUST include an Unsupported (Section
      20.40) header field listing those option-tags the element did not
      understand.

   6. Proxy-Authorization check

      If an element requires credentials before forwarding a request,
      the request MUST be inspected as described in Section 22.3.  That
      section also defines what the element must do if the inspection
      fails.

16.4 Route Information Preprocessing

   The proxy MUST inspect the Request-URI of the request.  If the
   Request-URI of the request contains a value this proxy previously
   placed into a Record-Route header field (see Section 16.6 item 4),
   the proxy MUST replace the Request-URI in the request with the last
   value from the Route header field, and remove that value from the
   Route header field.  The proxy MUST then proceed as if it received
   this modified request.

      This will only happen when the element sending the request to the
      proxy (which may have been an endpoint) is a strict router.  This
      rewrite on receive is necessary to enable backwards compatibility
      with those elements.  It also allows elements following this
      specification to preserve the Request-URI through strict-routing
      proxies (see Section 12.2.1.1).

      This requirement does not obligate a proxy to keep state in order
      to detect URIs it previously placed in Record-Route header fields.
      Instead, a proxy need only place enough information in those URIs
      to recognize them as values it provided when they later appear.

   If the Request-URI contains a maddr parameter, the proxy MUST check
   to see if its value is in the set of addresses or domains the proxy
   is configured to be responsible for.  If the Request-URI has a maddr
   parameter with a value the proxy is responsible for, and the request
   was received using the port and transport indicated (explicitly or by
   default) in the Request-URI, the proxy MUST strip the maddr and any
   non-default port or transport parameter and continue processing as if
   those values had not been present in the request.

Top      Up      ToC       Page 97 
      A request may arrive with a maddr matching the proxy, but on a
      port or transport different from that indicated in the URI.  Such
      a request needs to be forwarded to the proxy using the indicated
      port and transport.

   If the first value in the Route header field indicates this proxy,
   the proxy MUST remove that value from the request.

16.5 Determining Request Targets

   Next, the proxy calculates the target(s) of the request.  The set of
   targets will either be predetermined by the contents of the request
   or will be obtained from an abstract location service.  Each target
   in the set is represented as a URI.

   If the Request-URI of the request contains an maddr parameter, the
   Request-URI MUST be placed into the target set as the only target
   URI, and the proxy MUST proceed to Section 16.6.

   If the domain of the Request-URI indicates a domain this element is
   not responsible for, the Request-URI MUST be placed into the target
   set as the only target, and the element MUST proceed to the task of
   Request Forwarding (Section 16.6).

      There are many circumstances in which a proxy might receive a
      request for a domain it is not responsible for.  A firewall proxy
      handling outgoing calls (the way HTTP proxies handle outgoing
      requests) is an example of where this is likely to occur.

   If the target set for the request has not been predetermined as
   described above, this implies that the element is responsible for the
   domain in the Request-URI, and the element MAY use whatever mechanism
   it desires to determine where to send the request.  Any of these
   mechanisms can be modeled as accessing an abstract Location Service.
   This may consist of obtaining information from a location service
   created by a SIP Registrar, reading a database, consulting a presence
   server, utilizing other protocols, or simply performing an
   algorithmic substitution on the Request-URI.  When accessing the
   location service constructed by a registrar, the Request-URI MUST
   first be canonicalized as described in Section 10.3 before being used
   as an index.  The output of these mechanisms is used to construct the
   target set.

   If the Request-URI does not provide sufficient information for the
   proxy to determine the target set, it SHOULD return a 485 (Ambiguous)
   response.  This response SHOULD contain a Contact header field
   containing URIs of new addresses to be tried.  For example, an INVITE

Top      Up      ToC       Page 98 
   to sip:John.Smith@company.com may be ambiguous at a proxy whose
   location service has multiple John Smiths listed.  See Section
   21.4.23 for details.

   Any information in or about the request or the current environment of
   the element MAY be used in the construction of the target set.  For
   instance, different sets may be constructed depending on contents or
   the presence of header fields and bodies, the time of day of the
   request's arrival, the interface on which the request arrived,
   failure of previous requests, or even the element's current level of
   utilization.

   As potential targets are located through these services, their URIs
   are added to the target set.  Targets can only be placed in the
   target set once.  If a target URI is already present in the set
   (based on the definition of equality for the URI type), it MUST NOT
   be added again.

   A proxy MUST NOT add additional targets to the target set if the
   Request-URI of the original request does not indicate a resource this
   proxy is responsible for.

      A proxy can only change the Request-URI of a request during
      forwarding if it is responsible for that URI.  If the proxy is not
      responsible for that URI, it will not recurse on 3xx or 416
      responses as described below.

   If the Request-URI of the original request indicates a resource this
   proxy is responsible for, the proxy MAY continue to add targets to
   the set after beginning Request Forwarding.  It MAY use any
   information obtained during that processing to determine new targets.
   For instance, a proxy may choose to incorporate contacts obtained in
   a redirect response (3xx) into the target set.  If a proxy uses a
   dynamic source of information while building the target set (for
   instance, if it consults a SIP Registrar), it SHOULD monitor that
   source for the duration of processing the request.  New locations
   SHOULD be added to the target set as they become available.  As
   above, any given URI MUST NOT be added to the set more than once.

      Allowing a URI to be added to the set only once reduces
      unnecessary network traffic, and in the case of incorporating
      contacts from redirect requests prevents infinite recursion.

   For example, a trivial location service is a "no-op", where the
   target URI is equal to the incoming request URI.  The request is sent
   to a specific next hop proxy for further processing.  During request

Top      Up      ToC       Page 99 
   forwarding of Section 16.6, Item 6, the identity of that next hop,
   expressed as a SIP or SIPS URI, is inserted as the top-most Route
   header field value into the request.

   If the Request-URI indicates a resource at this proxy that does not
   exist, the proxy MUST return a 404 (Not Found) response.

   If the target set remains empty after applying all of the above, the
   proxy MUST return an error response, which SHOULD be the 480
   (Temporarily Unavailable) response.

16.6 Request Forwarding

   As soon as the target set is non-empty, a proxy MAY begin forwarding
   the request.  A stateful proxy MAY process the set in any order.  It
   MAY process multiple targets serially, allowing each client
   transaction to complete before starting the next.  It MAY start
   client transactions with every target in parallel.  It also MAY
   arbitrarily divide the set into groups, processing the groups
   serially and processing the targets in each group in parallel.

   A common ordering mechanism is to use the qvalue parameter of targets
   obtained from Contact header fields (see Section 20.10).  Targets are
   processed from highest qvalue to lowest.  Targets with equal qvalues
   may be processed in parallel.

   A stateful proxy must have a mechanism to maintain the target set as
   responses are received and associate the responses to each forwarded
   request with the original request.  For the purposes of this model,
   this mechanism is a "response context" created by the proxy layer
   before forwarding the first request.

   For each target, the proxy forwards the request following these
   steps:

      1.  Make a copy of the received request

      2.  Update the Request-URI

      3.  Update the Max-Forwards header field

      4.  Optionally add a Record-route header field value

      5.  Optionally add additional header fields

      6.  Postprocess routing information

      7.  Determine the next-hop address, port, and transport

Top      Up      ToC       Page 100 
      8.  Add a Via header field value

      9.  Add a Content-Length header field if necessary

      10. Forward the new request

      11. Set timer C

   Each of these steps is detailed below:

      1. Copy request

         The proxy starts with a copy of the received request.  The copy
         MUST initially contain all of the header fields from the
         received request.  Fields not detailed in the processing
         described below MUST NOT be removed.  The copy SHOULD maintain
         the ordering of the header fields as in the received request.
         The proxy MUST NOT reorder field values with a common field
         name (See Section 7.3.1).  The proxy MUST NOT add to, modify,
         or remove the message body.

         An actual implementation need not perform a copy; the primary
         requirement is that the processing for each next hop begin with
         the same request.

      2. Request-URI

         The Request-URI in the copy's start line MUST be replaced with
         the URI for this target.  If the URI contains any parameters
         not allowed in a Request-URI, they MUST be removed.

         This is the essence of a proxy's role.  This is the mechanism
         through which a proxy routes a request toward its destination.

         In some circumstances, the received Request-URI is placed into
         the target set without being modified.  For that target, the
         replacement above is effectively a no-op.

      3. Max-Forwards

         If the copy contains a Max-Forwards header field, the proxy
         MUST decrement its value by one (1).

         If the copy does not contain a Max-Forwards header field, the
         proxy MUST add one with a field value, which SHOULD be 70.

         Some existing UAs will not provide a Max-Forwards header field
         in a request.

Top      Up      ToC       Page 101 
      4. Record-Route

         If this proxy wishes to remain on the path of future requests
         in a dialog created by this request (assuming the request
         creates a dialog), it MUST insert a Record-Route header field
         value into the copy before any existing Record-Route header
         field values, even if a Route header field is already present.

         Requests establishing a dialog may contain a preloaded Route
         header field.

         If this request is already part of a dialog, the proxy SHOULD
         insert a Record-Route header field value if it wishes to remain
         on the path of future requests in the dialog.  In normal
         endpoint operation as described in Section 12, these Record-
         Route header field values will not have any effect on the route
         sets used by the endpoints.

         The proxy will remain on the path if it chooses to not insert a
         Record-Route header field value into requests that are already
         part of a dialog.  However, it would be removed from the path
         when an endpoint that has failed reconstitutes the dialog.

         A proxy MAY insert a Record-Route header field value into any
         request.  If the request does not initiate a dialog, the
         endpoints will ignore the value.  See Section 12 for details on
         how endpoints use the Record-Route header field values to
         construct Route header fields.

         Each proxy in the path of a request chooses whether to add a
         Record-Route header field value independently - the presence of
         a Record-Route header field in a request does not obligate this
         proxy to add a value.

         The URI placed in the Record-Route header field value MUST be a
         SIP or SIPS URI.  This URI MUST contain an lr parameter (see
         Section 19.1.1).  This URI MAY be different for each
         destination the request is forwarded to.  The URI SHOULD NOT
         contain the transport parameter unless the proxy has knowledge
         (such as in a private network) that the next downstream element
         that will be in the path of subsequent requests supports that
         transport.

         The URI this proxy provides will be used by some other element
         to make a routing decision.  This proxy, in general, has no way
         of knowing the capabilities of that element, so it must
         restrict itself to the mandatory elements of a SIP
         implementation: SIP URIs and either the TCP or UDP transports.

Top      Up      ToC       Page 102 
         The URI placed in the Record-Route header field MUST resolve to
         the element inserting it (or a suitable stand-in) when the
         server location procedures of [4] are applied to it, so that
         subsequent requests reach the same SIP element.  If the
         Request-URI contains a SIPS URI, or the topmost Route header
         field value (after the post processing of bullet 6) contains a
         SIPS URI, the URI placed into the Record-Route header field
         MUST be a SIPS URI.  Furthermore, if the request was not
         received over TLS, the proxy MUST insert a Record-Route header
         field.  In a similar fashion, a proxy that receives a request
         over TLS, but generates a request without a SIPS URI in the
         Request-URI or topmost Route header field value (after the post
         processing of bullet 6), MUST insert a Record-Route header
         field that is not a SIPS URI.

         A proxy at a security perimeter must remain on the perimeter
         throughout the dialog.

         If the URI placed in the Record-Route header field needs to be
         rewritten when it passes back through in a response, the URI
         MUST be distinct enough to locate at that time.  (The request
         may spiral through this proxy, resulting in more than one
         Record-Route header field value being added).  Item 8 of
         Section 16.7 recommends a mechanism to make the URI
         sufficiently distinct.

         The proxy MAY include parameters in the Record-Route header
         field value.  These will be echoed in some responses to the
         request such as the 200 (OK) responses to INVITE.  Such
         parameters may be useful for keeping state in the message
         rather than the proxy.

         If a proxy needs to be in the path of any type of dialog (such
         as one straddling a firewall), it SHOULD add a Record-Route
         header field value to every request with a method it does not
         understand since that method may have dialog semantics.

         The URI a proxy places into a Record-Route header field is only
         valid for the lifetime of any dialog created by the transaction
         in which it occurs.  A dialog-stateful proxy, for example, MAY
         refuse to accept future requests with that value in the
         Request-URI after the dialog has terminated.  Non-dialog-
         stateful proxies, of course, have no concept of when the dialog
         has terminated, but they MAY encode enough information in the
         value to compare it against the dialog identifier of future
         requests and MAY reject requests not matching that information.
         Endpoints MUST NOT use a URI obtained from a Record-Route
         header field outside the dialog in which it was provided.  See

Top      Up      ToC       Page 103 
         Section 12 for more information on an endpoint's use of
         Record-Route header fields.

         Record-routing may be required by certain services where the
         proxy needs to observe all messages in a dialog.  However, it
         slows down processing and impairs scalability and thus proxies
         should only record-route if required for a particular service.

         The Record-Route process is designed to work for any SIP
         request that initiates a dialog.  INVITE is the only such
         request in this specification, but extensions to the protocol
         MAY define others.

      5. Add Additional Header Fields

         The proxy MAY add any other appropriate header fields to the
         copy at this point.

      6. Postprocess routing information

         A proxy MAY have a local policy that mandates that a request
         visit a specific set of proxies before being delivered to the
         destination.  A proxy MUST ensure that all such proxies are
         loose routers.  Generally, this can only be known with
         certainty if the proxies are within the same administrative
         domain.  This set of proxies is represented by a set of URIs
         (each of which contains the lr parameter).  This set MUST be
         pushed into the Route header field of the copy ahead of any
         existing values, if present.  If the Route header field is
         absent, it MUST be added, containing that list of URIs.

         If the proxy has a local policy that mandates that the request
         visit one specific proxy, an alternative to pushing a Route
         value into the Route header field is to bypass the forwarding
         logic of item 10 below, and instead just send the request to
         the address, port, and transport for that specific proxy.  If
         the request has a Route header field, this alternative MUST NOT
         be used unless it is known that next hop proxy is a loose
         router.  Otherwise, this approach MAY be used, but the Route
         insertion mechanism above is preferred for its robustness,
         flexibility, generality and consistency of operation.
         Furthermore, if the Request-URI contains a SIPS URI, TLS MUST
         be used to communicate with that proxy.

         If the copy contains a Route header field, the proxy MUST
         inspect the URI in its first value.  If that URI does not
         contain an lr parameter, the proxy MUST modify the copy as
         follows:

Top      Up      ToC       Page 104 
         -  The proxy MUST place the Request-URI into the Route header
            field as the last value.

         -  The proxy MUST then place the first Route header field value
            into the Request-URI and remove that value from the Route
            header field.

         Appending the Request-URI to the Route header field is part of
         a mechanism used to pass the information in that Request-URI
         through strict-routing elements.  "Popping" the first Route
         header field value into the Request-URI formats the message the
         way a strict-routing element expects to receive it (with its
         own URI in the Request-URI and the next location to visit in
         the first Route header field value).

      7. Determine Next-Hop Address, Port, and Transport

         The proxy MAY have a local policy to send the request to a
         specific IP address, port, and transport, independent of the
         values of the Route and Request-URI.  Such a policy MUST NOT be
         used if the proxy is not certain that the IP address, port, and
         transport correspond to a server that is a loose router.
         However, this mechanism for sending the request through a
         specific next hop is NOT RECOMMENDED; instead a Route header
         field should be used for that purpose as described above.

         In the absence of such an overriding mechanism, the proxy
         applies the procedures listed in [4] as follows to determine
         where to send the request.  If the proxy has reformatted the
         request to send to a strict-routing element as described in
         step 6 above, the proxy MUST apply those procedures to the
         Request-URI of the request.  Otherwise, the proxy MUST apply
         the procedures to the first value in the Route header field, if
         present, else the Request-URI.  The procedures will produce an
         ordered set of (address, port, transport) tuples.
         Independently of which URI is being used as input to the
         procedures of [4], if the Request-URI specifies a SIPS
         resource, the proxy MUST follow the procedures of [4] as if the
         input URI were a SIPS URI.

         As described in [4], the proxy MUST attempt to deliver the
         message to the first tuple in that set, and proceed through the
         set in order until the delivery attempt succeeds.

         For each tuple attempted, the proxy MUST format the message as
         appropriate for the tuple and send the request using a new
         client transaction as detailed in steps 8 through 10.

Top      Up      ToC       Page 105

Updated by:  RFC 5393/4.2.1 
         Since each attempt uses a new client transaction, it represents
         a new branch.  Thus, the branch parameter provided with the Via
         header field inserted in step 8 MUST be different for each
         attempt.

         If the client transaction reports failure to send the request
         or a timeout from its state machine, the proxy continues to the
         next address in that ordered set.  If the ordered set is
         exhausted, the request cannot be forwarded to this element in
         the target set.  The proxy does not need to place anything in
         the response context, but otherwise acts as if this element of
         the target set returned a 408 (Request Timeout) final response.

      8. Add a Via header field value

         The proxy MUST insert a Via header field value into the copy
         before the existing Via header field values.  The construction
         of this value follows the same guidelines of Section 8.1.1.7.
         This implies that the proxy will compute its own branch
         parameter, which will be globally unique for that branch, and
         contain the requisite magic cookie. Note that this implies that
         the branch parameter will be different for different instances
         of a spiraled or looped request through a proxy.

         Proxies choosing to detect loops have an additional constraint
         in the value they use for construction of the branch parameter.
         A proxy choosing to detect loops SHOULD create a branch
         parameter separable into two parts by the implementation.  The
         first part MUST satisfy the constraints of Section 8.1.1.7 as
         described above.  The second is used to perform loop detection
         and distinguish loops from spirals.

         Loop detection is performed by verifying that, when a request
         returns to a proxy, those fields having an impact on the
         processing of the request have not changed.  The value placed
         in this part of the branch parameter SHOULD reflect all of
         those fields (including any Route, Proxy-Require and Proxy-
         Authorization header fields).  This is to ensure that if the
         request is routed back to the proxy and one of those fields
         changes, it is treated as a spiral and not a loop (see Section
         16.3).  A common way to create this value is to compute a
         cryptographic hash of the To tag, From tag, Call-ID header
         field, the Request-URI of the request received (before
         translation), the topmost Via header, and the sequence number
         from the CSeq header field, in addition to any Proxy-Require
         and Proxy-Authorization header fields that may be present.  The

Top      Up      ToC       Page 106 
         algorithm used to compute the hash is implementation-dependent,
         but MD5 (RFC 1321 [35]), expressed in hexadecimal, is a
         reasonable choice.  (Base64 is not permissible for a token.)

         If a proxy wishes to detect loops, the "branch" parameter it
         supplies MUST depend on all information affecting processing of
         a request, including the incoming Request-URI and any header
         fields affecting the request's admission or routing.  This is
         necessary to distinguish looped requests from requests whose
         routing parameters have changed before returning to this
         server.

         The request method MUST NOT be included in the calculation of
         the branch parameter.  In particular, CANCEL and ACK requests
         (for non-2xx responses) MUST have the same branch value as the
         corresponding request they cancel or acknowledge.  The branch
         parameter is used in correlating those requests at the server
         handling them (see Sections 17.2.3 and 9.2).
   The proxy MUST insert a Via header field value into the copy before
   the existing Via header field values.  The construction of this value
   follows the same guidelines of Section 8.1.1.7.  This implies that
   the proxy will compute its own branch parameter, which will be
   globally unique for that branch, and will contain the requisite magic
   cookie.  Note that following only the guidelines in Section 8.1.1.7
   will result in a branch parameter that will be different for
   different instances of a spiraled or looped request through a proxy.

   Proxies required to perform loop detection by RFC 5393 have an
   additional constraint on the value they place in the Via header
   field.  Such proxies SHOULD create a branch value separable into two
   parts in any implementation-dependent way.

   The remainder of this section's description assumes the existence of
   these two parts.  If a proxy chooses to employ some other mechanism,
   it is the implementer's responsibility to verify that the detection
   properties defined by the requirements placed on these two parts are
   achieved.

   The first part of the branch value MUST satisfy the constraints of
   Section 8.1.1.7.  The second part is used to perform loop detection
   and distinguish loops from spirals.

   This second part MUST vary with any field used by the location
   service logic in determining where to retarget or forward this
   request.  This is necessary to distinguish looped requests from
   spirals by allowing the proxy to recognize if none of the values
   affecting the processing of the request have changed.  Hence, the
   second part MUST depend at least on the received Request-URI and any
   Route header field values used when processing the received request.
   Implementers need to take care to include all fields used by the
   location service logic in that particular implementation.

   This second part MUST NOT vary with the request method.  CANCEL and
   non-200 ACK requests MUST have the same branch parameter value as the
   corresponding request they cancel or acknowledge.  This branch
   parameter value is used in correlating those requests at the server
   handling them (see Sections 17.2.3 and 9.2).
      9. Add a Content-Length header field if necessary

         If the request will be sent to the next hop using a stream-
         based transport and the copy contains no Content-Length header
         field, the proxy MUST insert one with the correct value for the
         body of the request (see Section 20.14).

      10. Forward Request

         A stateful proxy MUST create a new client transaction for this
         request as described in Section 17.1 and instructs the
         transaction to send the request using the address, port and
         transport determined in step 7.

      11. Set timer C

         In order to handle the case where an INVITE request never
         generates a final response, the TU uses a timer which is called
         timer C.  Timer C MUST be set for each client transaction when
         an INVITE request is proxied.  The timer MUST be larger than 3
         minutes.  Section 16.7 bullet 2 discusses how this timer is
         updated with provisional responses, and Section 16.8 discusses
         processing when it fires.

Top      Up      ToC       Page 107

Updated by:  RFC 6026/8.2 
16.7 Response Processing

   When a response is received by an element, it first tries to locate a
   client transaction (Section 17.1.3) matching the response.  If none
   is found, the element MUST process the response (even if it is an
   informational response) as a stateless proxy (described below).  If a
   match is found, the response is handed to the client transaction.

      Forwarding responses for which a client transaction (or more
      generally any knowledge of having sent an associated request) is
      not found improves robustness.  In particular, it ensures that
      "late" 2xx responses to INVITE requests are forwarded properly.
      When a response is received by an element, it first tries to
      locate a client transaction (Section 17.1.3) matching the
      response.  If a transaction is found, the response is handed to
      the client transaction.  If none is found, the element MUST NOT
      forward the response.
   As client transactions pass responses to the proxy layer, the
   following processing MUST take place:

      1.  Find the appropriate response context

      2.  Update timer C for provisional responses

      3.  Remove the topmost Via

      4.  Add the response to the response context

      5.  Check to see if this response should be forwarded immediately

      6.  When necessary, choose the best final response from the
          response context

   If no final response has been forwarded after every client
   transaction associated with the response context has been terminated,
   the proxy must choose and forward the "best" response from those it
   has seen so far.

   The following processing MUST be performed on each response that is
   forwarded.  It is likely that more than one response to each request
   will be forwarded: at least each provisional and one final response.

      7.  Aggregate authorization header field values if necessary

      8.  Optionally rewrite Record-Route header field values

      9.  Forward the response

      10. Generate any necessary CANCEL requests

Top      Up      ToC       Page 108 
   Each of the above steps are detailed below:

      1.  Find Context

         The proxy locates the "response context" it created before
         forwarding the original request using the key described in
         Section 16.6.  The remaining processing steps take place in
         this context.

      2.  Update timer C for provisional responses

         For an INVITE transaction, if the response is a provisional
         response with status codes 101 to 199 inclusive (i.e., anything
         but 100), the proxy MUST reset timer C for that client
         transaction.  The timer MAY be reset to a different value, but
         this value MUST be greater than 3 minutes.

      3.  Via

         The proxy removes the topmost Via header field value from the
         response.

         If no Via header field values remain in the response, the
         response was meant for this element and MUST NOT be forwarded.
         The remainder of the processing described in this section is
         not performed on this message, the UAC processing rules
         described in Section 8.1.3 are followed instead (transport
         layer processing has already occurred).

         This will happen, for instance, when the element generates
         CANCEL requests as described in Section 10.

      4.  Add response to context

         Final responses received are stored in the response context
         until a final response is generated on the server transaction
         associated with this context.  The response may be a candidate
         for the best final response to be returned on that server
         transaction.  Information from this response may be needed in
         forming the best response, even if this response is not chosen.

         If the proxy chooses to recurse on any contacts in a 3xx
         response by adding them to the target set, it MUST remove them
         from the response before adding the response to the response
         context.  However, a proxy SHOULD NOT recurse to a non-SIPS URI
         if the Request-URI of the original request was a SIPS URI.  If

Top      Up      ToC       Page 109 
         the proxy recurses on all of the contacts in a 3xx response,
         the proxy SHOULD NOT add the resulting contactless response to
         the response context.

         Removing the contact before adding the response to the response
         context prevents the next element upstream from retrying a
         location this proxy has already attempted.

         3xx responses may contain a mixture of SIP, SIPS, and non-SIP
         URIs.  A proxy may choose to recurse on the SIP and SIPS URIs
         and place the remainder into the response context to be
         returned, potentially in the final response.

         If a proxy receives a 416 (Unsupported URI Scheme) response to
         a request whose Request-URI scheme was not SIP, but the scheme
         in the original received request was SIP or SIPS (that is, the
         proxy changed the scheme from SIP or SIPS to something else
         when it proxied a request), the proxy SHOULD add a new URI to
         the target set.  This URI SHOULD be a SIP URI version of the
         non-SIP URI that was just tried.  In the case of the tel URL,
         this is accomplished by placing the telephone-subscriber part
         of the tel URL into the user part of the SIP URI, and setting
         the hostpart to the domain where the prior request was sent.
         See Section 19.1.6 for more detail on forming SIP URIs from tel
         URLs.

         As with a 3xx response, if a proxy "recurses" on the 416 by
         trying a SIP or SIPS URI instead, the 416 response SHOULD NOT
         be added to the response context.

      5.  Check response for forwarding

         Until a final response has been sent on the server transaction,
         the following responses MUST be forwarded immediately:

         -  Any provisional response other than 100 (Trying)

         -  Any 2xx response

         If a 6xx response is received, it is not immediately forwarded,
         but the stateful proxy SHOULD cancel all client pending
         transactions as described in Section 10, and it MUST NOT create
         any new branches in this context.

         This is a change from RFC 2543, which mandated that the proxy
         was to forward the 6xx response immediately.  For an INVITE
         transaction, this approach had the problem that a 2xx response
         could arrive on another branch, in which case the proxy would

Top      Up      ToC       Page 110 
         have to forward the 2xx.  The result was that the UAC could
         receive a 6xx response followed by a 2xx response, which should
         never be allowed to happen.  Under the new rules, upon
         receiving a 6xx, a proxy will issue a CANCEL request, which
         will generally result in 487 responses from all outstanding
         client transactions, and then at that point the 6xx is
         forwarded upstream.

         After a final response has been sent on the server transaction,
         the following responses MUST be forwarded immediately:

         -  Any 2xx response to an INVITE request

         A stateful proxy MUST NOT immediately forward any other
         responses.  In particular, a stateful proxy MUST NOT forward
         any 100 (Trying) response.  Those responses that are candidates
         for forwarding later as the "best" response have been gathered
         as described in step "Add Response to Context".

         Any response chosen for immediate forwarding MUST be processed
         as described in steps "Aggregate Authorization Header Field
         Values" through "Record-Route".

         This step, combined with the next, ensures that a stateful
         proxy will forward exactly one final response to a non-INVITE
         request, and either exactly one non-2xx response or one or more
         2xx responses to an INVITE request.

      6.  Choosing the best response

         A stateful proxy MUST send a final response to a response
         context's server transaction if no final responses have been
         immediately forwarded by the above rules and all client
         transactions in this response context have been terminated.

         The stateful proxy MUST choose the "best" final response among
         those received and stored in the response context.

         If there are no final responses in the context, the proxy MUST
         send a 408 (Request Timeout) response to the server
         transaction.

         Otherwise, the proxy MUST forward a response from the responses
         stored in the response context.  It MUST choose from the 6xx
         class responses if any exist in the context.  If no 6xx class
         responses are present, the proxy SHOULD choose from the lowest
         response class stored in the response context.  The proxy MAY
         select any response within that chosen class.  The proxy SHOULD

Top      Up      ToC       Page 111 
         give preference to responses that provide information affecting
         resubmission of this request, such as 401, 407, 415, 420, and
         484 if the 4xx class is chosen.

         A proxy which receives a 503 (Service Unavailable) response
         SHOULD NOT forward it upstream unless it can determine that any
         subsequent requests it might proxy will also generate a 503.
         In other words, forwarding a 503 means that the proxy knows it
         cannot service any requests, not just the one for the Request-
         URI in the request which generated the 503.  If the only
         response that was received is a 503, the proxy SHOULD generate
         a 500 response and forward that upstream.

         The forwarded response MUST be processed as described in steps
         "Aggregate Authorization Header Field Values" through "Record-
         Route".

         For example, if a proxy forwarded a request to 4 locations, and
         received 503, 407, 501, and 404 responses, it may choose to
         forward the 407 (Proxy Authentication Required) response.

         1xx and 2xx responses may be involved in the establishment of
         dialogs.  When a request does not contain a To tag, the To tag
         in the response is used by the UAC to distinguish multiple
         responses to a dialog creating request.  A proxy MUST NOT
         insert a tag into the To header field of a 1xx or 2xx response
         if the request did not contain one.  A proxy MUST NOT modify
         the tag in the To header field of a 1xx or 2xx response.

         Since a proxy may not insert a tag into the To header field of
         a 1xx response to a request that did not contain one, it cannot
         issue non-100 provisional responses on its own.  However, it
         can branch the request to a UAS sharing the same element as the
         proxy.  This UAS can return its own provisional responses,
         entering into an early dialog with the initiator of the
         request.  The UAS does not have to be a discreet process from
         the proxy.  It could be a virtual UAS implemented in the same
         code space as the proxy.

         3-6xx responses are delivered hop-by-hop.  When issuing a 3-6xx
         response, the element is effectively acting as a UAS, issuing
         its own response, usually based on the responses received from
         downstream elements.  An element SHOULD preserve the To tag
         when simply forwarding a 3-6xx response to a request that did
         not contain a To tag.

         A proxy MUST NOT modify the To tag in any forwarded response to
         a request that contains a To tag.

Top      Up      ToC       Page 112

Updated by:  RFC 5630/A 
         While it makes no difference to the upstream elements if the
         proxy replaced the To tag in a forwarded 3-6xx response,
         preserving the original tag may assist with debugging.

         When the proxy is aggregating information from several
         responses, choosing a To tag from among them is arbitrary, and
         generating a new To tag may make debugging easier.  This
         happens, for instance, when combining 401 (Unauthorized) and
         407 (Proxy Authentication Required) challenges, or combining
         Contact values from unencrypted and unauthenticated 3xx
         responses.

      7.  Aggregate Authorization Header Field Values

         If the selected response is a 401 (Unauthorized) or 407 (Proxy
         Authentication Required), the proxy MUST collect any WWW-
         Authenticate and Proxy-Authenticate header field values from
         all other 401 (Unauthorized) and 407 (Proxy Authentication
         Required) responses received so far in this response context
         and add them to this response without modification before
         forwarding.  The resulting 401 (Unauthorized) or 407 (Proxy
         Authentication Required) response could have several WWW-
         Authenticate AND Proxy-Authenticate header field values.

         This is necessary because any or all of the destinations the
         request was forwarded to may have requested credentials.  The
         client needs to receive all of those challenges and supply
         credentials for each of them when it retries the request.
         Motivation for this behavior is provided in Section 26.

      8.  Record-Route

         If the selected response contains a Record-Route header field
         value originally provided by this proxy, the proxy MAY choose
         to rewrite the value before forwarding the response.  This
         allows the proxy to provide different URIs for itself to the
         next upstream and downstream elements.  A proxy may choose to
         use this mechanism for any reason.  For instance, it is useful
         for multi-homed hosts.

         If the proxy received the request over TLS, and sent it out
         over a non-TLS connection, the proxy MUST rewrite the URI in
         the Record-Route header field to be a SIPS URI.  If the proxy
         received the request over a non-TLS connection, and sent it out
         over TLS, the proxy MUST rewrite the URI in the Record-Route
         header field to be a SIP URI.

Top      Up      ToC       Page 113 
         The new URI provided by the proxy MUST satisfy the same
         constraints on URIs placed in Record-Route header fields in
         requests (see Step 4 of Section 16.6) with the following
         modifications:

         The URI SHOULD NOT contain the transport parameter unless the
         proxy has knowledge that the next upstream (as opposed to
         downstream) element that will be in the path of subsequent
         requests supports that transport.

         When a proxy does decide to modify the Record-Route header
         field in the response, one of the operations it performs is
         locating the Record-Route value that it had inserted.  If the
         request spiraled, and the proxy inserted a Record-Route value
         in each iteration of the spiral, locating the correct value in
         the response (which must be the proper iteration in the reverse
         direction) is tricky.  The rules above recommend that a proxy
         wishing to rewrite Record-Route header field values insert
         sufficiently distinct URIs into the Record-Route header field
         so that the right one may be selected for rewriting.  A
         RECOMMENDED mechanism to achieve this is for the proxy to
         append a unique identifier for the proxy instance to the user
         portion of the URI.

         When the response arrives, the proxy modifies the first
         Record-Route whose identifier matches the proxy instance.  The
         modification results in a URI without this piece of data
         appended to the user portion of the URI.  Upon the next
         iteration, the same algorithm (find the topmost Record-Route
         header field value with the parameter) will correctly extract
         the next Record-Route header field value inserted by that
         proxy.

         Not every response to a request to which a proxy adds a
         Record-Route header field value will contain a Record-Route
         header field.  If the response does contain a Record-Route
         header field, it will contain the value the proxy added.

      9.  Forward response

         After performing the processing described in steps "Aggregate
         Authorization Header Field Values" through "Record-Route", the
         proxy MAY perform any feature specific manipulations on the
         selected response.  The proxy MUST NOT add to, modify, or
         remove the message body.  Unless otherwise specified, the proxy
         MUST NOT remove any header field values other than the Via
         header field value discussed in Section 16.7 Item 3.  In
         particular, the proxy MUST NOT remove any "received" parameter

Top      Up      ToC       Page 114

Updated by:  RFC 6026/8.3 
         it may have added to the next Via header field value while
         processing the request associated with this response.  The
         proxy MUST pass the response to the server transaction
         associated with the response context.  This will result in the
         response being sent to the location now indicated in the
         topmost Via header field value.  If the server transaction is
         no longer available to handle the transmission, the element
         MUST forward the response statelessly by sending it to the
         server transport.
      If the server transaction is no longer available to handle the
      transmission, the response is simply discarded.
                            The server transaction might indicate
         failure to send the response or signal a timeout in its state
         machine.  These errors would be logged for diagnostic purposes
         as appropriate, but the protocol requires no remedial action
         from the proxy.

         The proxy MUST maintain the response context until all of its
         associated transactions have been terminated, even after
         forwarding a final response.

      10. Generate CANCELs

         If the forwarded response was a final response, the proxy MUST
         generate a CANCEL request for all pending client transactions
         associated with this response context.  A proxy SHOULD also
         generate a CANCEL request for all pending client transactions
         associated with this response context when it receives a 6xx
         response.  A pending client transaction is one that has
         received a provisional response, but no final response (it is
         in the proceeding state) and has not had an associated CANCEL
         generated for it.  Generating CANCEL requests is described in
         Section 9.1.

         The requirement to CANCEL pending client transactions upon
         forwarding a final response does not guarantee that an endpoint
         will not receive multiple 200 (OK) responses to an INVITE.  200
         (OK) responses on more than one branch may be generated before
         the CANCEL requests can be sent and processed.  Further, it is
         reasonable to expect that a future extension may override this
         requirement to issue CANCEL requests.

16.8 Processing Timer C

   If timer C should fire, the proxy MUST either reset the timer with
   any value it chooses, or terminate the client transaction.  If the
   client transaction has received a provisional response, the proxy
   MUST generate a CANCEL request matching that transaction.  If the
   client transaction has not received a provisional response, the proxy
   MUST behave as if the transaction received a 408 (Request Timeout)
   response.

Top      Up      ToC       Page 115 
   Allowing the proxy to reset the timer allows the proxy to dynamically
   extend the transaction's lifetime based on current conditions (such
   as utilization) when the timer fires.

16.9 Handling Transport Errors

   If the transport layer notifies a proxy of an error when it tries to
   forward a request (see Section 18.4), the proxy MUST behave as if the
   forwarded request received a 503 (Service Unavailable) response.

   If the proxy is notified of an error when forwarding a response, it
   drops the response.  The proxy SHOULD NOT cancel any outstanding
   client transactions associated with this response context due to this
   notification.

      If a proxy cancels its outstanding client transactions, a single
      malicious or misbehaving client can cause all transactions to fail
      through its Via header field.

16.10 CANCEL Processing

   A stateful proxy MAY generate a CANCEL to any other request it has
   generated at any time (subject to receiving a provisional response to
   that request as described in section 9.1).  A proxy MUST cancel any
   pending client transactions associated with a response context when
   it receives a matching CANCEL request.

   A stateful proxy MAY generate CANCEL requests for pending INVITE
   client transactions based on the period specified in the INVITE's
   Expires header field elapsing.  However, this is generally
   unnecessary since the endpoints involved will take care of signaling
   the end of the transaction.

   While a CANCEL request is handled in a stateful proxy by its own
   server transaction, a new response context is not created for it.
   Instead, the proxy layer searches its existing response contexts for
   the server transaction handling the request associated with this
   CANCEL.  If a matching response context is found, the element MUST
   immediately return a 200 (OK) response to the CANCEL request.  In
   this case, the element is acting as a user agent server as defined in
   Section 8.2.  Furthermore, the element MUST generate CANCEL requests
   for all pending client transactions in the context as described in
   Section 16.7 step 10.

   If a response context is not found, the element does not have any
   knowledge of the request to apply the CANCEL to.  It MUST statelessly
   forward the CANCEL request (it may have statelessly forwarded the
   associated request previously).

Top      Up      ToC       Page 116 
16.11 Stateless Proxy

   When acting statelessly, a proxy is a simple message forwarder.  Much
   of the processing performed when acting statelessly is the same as
   when behaving statefully.  The differences are detailed here.

   A stateless proxy does not have any notion of a transaction, or of
   the response context used to describe stateful proxy behavior.
   Instead, the stateless proxy takes messages, both requests and
   responses, directly from the transport layer (See section 18).  As a
   result, stateless proxies do not retransmit messages on their own.
   They do, however, forward all retransmissions they receive (they do
   not have the ability to distinguish a retransmission from the
   original message).  Furthermore, when handling a request statelessly,
   an element MUST NOT generate its own 100 (Trying) or any other
   provisional response.

   A stateless proxy MUST validate a request as described in Section
   16.3

   A stateless proxy MUST follow the request processing steps described
   in Sections 16.4 through 16.5 with the following exception:

      o  A stateless proxy MUST choose one and only one target from the
         target set.  This choice MUST only rely on fields in the
         message and time-invariant properties of the server.  In
         particular, a retransmitted request MUST be forwarded to the
         same destination each time it is processed.  Furthermore,
         CANCEL and non-Routed ACK requests MUST generate the same
         choice as their associated INVITE.

   A stateless proxy MUST follow the request processing steps described
   in Section 16.6 with the following exceptions:

      o  The requirement for unique branch IDs across space and time
         applies to stateless proxies as well.  However, a stateless
         proxy cannot simply use a random number generator to compute
         the first component of the branch ID, as described in Section
         16.6 bullet 8.  This is because retransmissions of a request
         need to have the same value, and a stateless proxy cannot tell
         a retransmission from the original request.  Therefore, the
         component of the branch parameter that makes it unique MUST be
         the same each time a retransmitted request is forwarded.  Thus
         for a stateless proxy, the branch parameter MUST be computed as
         a combinatoric function of message parameters which are
         invariant on retransmission.

Top      Up      ToC       Page 117 
         The stateless proxy MAY use any technique it likes to guarantee
         uniqueness of its branch IDs across transactions.  However, the
         following procedure is RECOMMENDED.  The proxy examines the
         branch ID in the topmost Via header field of the received
         request.  If it begins with the magic cookie, the first
         component of the branch ID of the outgoing request is computed
         as a hash of the received branch ID.  Otherwise, the first
         component of the branch ID is computed as a hash of the topmost
         Via, the tag in the To header field, the tag in the From header
         field, the Call-ID header field, the CSeq number (but not
         method), and the Request-URI from the received request.  One of
         these fields will always vary across two different
         transactions.

      o  All other message transformations specified in Section 16.6
         MUST result in the same transformation of a retransmitted
         request.  In particular, if the proxy inserts a Record-Route
         value or pushes URIs into the Route header field, it MUST place
         the same values in retransmissions of the request.  As for the
         Via branch parameter, this implies that the transformations
         MUST be based on time-invariant configuration or
         retransmission-invariant properties of the request.

      o  A stateless proxy determines where to forward the request as
         described for stateful proxies in Section 16.6 Item 10.  The
         request is sent directly to the transport layer instead of
         through a client transaction.

         Since a stateless proxy must forward retransmitted requests to
         the same destination and add identical branch parameters to
         each of them, it can only use information from the message
         itself and time-invariant configuration data for those
         calculations.  If the configuration state is not time-invariant
         (for example, if a routing table is updated) any requests that
         could be affected by the change may not be forwarded
         statelessly during an interval equal to the transaction timeout
         window before or after the change.  The method of processing
         the affected requests in that interval is an implementation
         decision.  A common solution is to forward them transaction
         statefully.

   Stateless proxies MUST NOT perform special processing for CANCEL
   requests.  They are processed by the above rules as any other
   requests.  In particular, a stateless proxy applies the same Route
   header field processing to CANCEL requests that it applies to any
   other request.

Top      Up      ToC       Page 118 
   Response processing as described in Section 16.7 does not apply to a
   proxy behaving statelessly.  When a response arrives at a stateless
   proxy, the proxy MUST inspect the sent-by value in the first
   (topmost) Via header field value.  If that address matches the proxy,
   (it equals a value this proxy has inserted into previous requests)
   the proxy MUST remove that header field value from the response and
   forward the result to the location indicated in the next Via header
   field value.  The proxy MUST NOT add to, modify, or remove the
   message body.  Unless specified otherwise, the proxy MUST NOT remove
   any other header field values.  If the address does not match the
   proxy, the message MUST be silently discarded.

16.12 Summary of Proxy Route Processing

   In the absence of local policy to the contrary, the processing a
   proxy performs on a request containing a Route header field can be
   summarized in the following steps.

      1.  The proxy will inspect the Request-URI.  If it indicates a
          resource owned by this proxy, the proxy will replace it with
          the results of running a location service.  Otherwise, the
          proxy will not change the Request-URI.

      2.  The proxy will inspect the URI in the topmost Route header
          field value.  If it indicates this proxy, the proxy removes it
          from the Route header field (this route node has been
          reached).

      3.  The proxy will forward the request to the resource indicated
          by the URI in the topmost Route header field value or in the
          Request-URI if no Route header field is present.  The proxy
          determines the address, port and transport to use when
          forwarding the request by applying the procedures in [4] to
          that URI.

   If no strict-routing elements are encountered on the path of the
   request, the Request-URI will always indicate the target of the
   request.

16.12.1 Examples

16.12.1.1 Basic SIP Trapezoid

   This scenario is the basic SIP trapezoid, U1 -> P1 -> P2 -> U2, with
   both proxies record-routing.  Here is the flow.

Top      Up      ToC       Page 119 
   U1 sends:

      INVITE sip:callee@domain.com SIP/2.0
      Contact: sip:caller@u1.example.com

   to P1.  P1 is an outbound proxy.  P1 is not responsible for
   domain.com, so it looks it up in DNS and sends it there.  It also
   adds a Record-Route header field value:

      INVITE sip:callee@domain.com SIP/2.0
      Contact: sip:caller@u1.example.com
      Record-Route: <sip:p1.example.com;lr>

   P2 gets this.  It is responsible for domain.com so it runs a location
   service and rewrites the Request-URI.  It also adds a Record-Route
   header field value.  There is no Route header field, so it resolves
   the new Request-URI to determine where to send the request:

      INVITE sip:callee@u2.domain.com SIP/2.0
      Contact: sip:caller@u1.example.com
      Record-Route: <sip:p2.domain.com;lr>
      Record-Route: <sip:p1.example.com;lr>

   The callee at u2.domain.com gets this and responds with a 200 OK:

      SIP/2.0 200 OK
      Contact: sip:callee@u2.domain.com
      Record-Route: <sip:p2.domain.com;lr>
      Record-Route: <sip:p1.example.com;lr>

   The callee at u2 also sets its dialog state's remote target URI to
   sip:caller@u1.example.com and its route set to:

      (<sip:p2.domain.com;lr>,<sip:p1.example.com;lr>)

   This is forwarded by P2 to P1 to U1 as normal.  Now, U1 sets its
   dialog state's remote target URI to sip:callee@u2.domain.com and its
   route set to:

      (<sip:p1.example.com;lr>,<sip:p2.domain.com;lr>)

   Since all the route set elements contain the lr parameter, U1
   constructs the following BYE request:

      BYE sip:callee@u2.domain.com SIP/2.0
      Route: <sip:p1.example.com;lr>,<sip:p2.domain.com;lr>

Top      Up      ToC       Page 120 
   As any other element (including proxies) would do, it resolves the
   URI in the topmost Route header field value using DNS to determine
   where to send the request.  This goes to P1.  P1 notices that it is
   not responsible for the resource indicated in the Request-URI so it
   doesn't change it.  It does see that it is the first value in the
   Route header field, so it removes that value, and forwards the
   request to P2:

      BYE sip:callee@u2.domain.com SIP/2.0
      Route: <sip:p2.domain.com;lr>

   P2 also notices it is not responsible for the resource indicated by
   the Request-URI (it is responsible for domain.com, not
   u2.domain.com), so it doesn't change it.  It does see itself in the
   first Route header field value, so it removes it and forwards the
   following to u2.domain.com based on a DNS lookup against the
   Request-URI:

      BYE sip:callee@u2.domain.com SIP/2.0

16.12.1.2 Traversing a Strict-Routing Proxy

   In this scenario, a dialog is established across four proxies, each
   of which adds Record-Route header field values.  The third proxy
   implements the strict-routing procedures specified in RFC 2543 and
   many works in progress.

      U1->P1->P2->P3->P4->U2

   The INVITE arriving at U2 contains:

      INVITE sip:callee@u2.domain.com SIP/2.0
      Contact: sip:caller@u1.example.com
      Record-Route: <sip:p4.domain.com;lr>
      Record-Route: <sip:p3.middle.com>
      Record-Route: <sip:p2.example.com;lr>
      Record-Route: <sip:p1.example.com;lr>

   Which U2 responds to with a 200 OK.  Later, U2 sends the following
   BYE request to P4 based on the first Route header field value.

      BYE sip:caller@u1.example.com SIP/2.0
      Route: <sip:p4.domain.com;lr>
      Route: <sip:p3.middle.com>
      Route: <sip:p2.example.com;lr>
      Route: <sip:p1.example.com;lr>

Top      Up      ToC       Page 121 
   P4 is not responsible for the resource indicated in the Request-URI
   so it will leave it alone.  It notices that it is the element in the
   first Route header field value so it removes it.  It then prepares to
   send the request based on the now first Route header field value of
   sip:p3.middle.com, but it notices that this URI does not contain the
   lr parameter, so before sending, it reformats the request to be:

      BYE sip:p3.middle.com SIP/2.0
      Route: <sip:p2.example.com;lr>
      Route: <sip:p1.example.com;lr>
      Route: <sip:caller@u1.example.com>

   P3 is a strict router, so it forwards the following to P2:

      BYE sip:p2.example.com;lr SIP/2.0
      Route: <sip:p1.example.com;lr>
      Route: <sip:caller@u1.example.com>

   P2 sees the request-URI is a value it placed into a Record-Route
   header field, so before further processing, it rewrites the request
   to be:

      BYE sip:caller@u1.example.com SIP/2.0
      Route: <sip:p1.example.com;lr>

   P2 is not responsible for u1.example.com, so it sends the request to
   P1 based on the resolution of the Route header field value.

   P1 notices itself in the topmost Route header field value, so it
   removes it, resulting in:

      BYE sip:caller@u1.example.com SIP/2.0

   Since P1 is not responsible for u1.example.com and there is no Route
   header field, P1 will forward the request to u1.example.com based on
   the Request-URI.

16.12.1.3 Rewriting Record-Route Header Field Values

   In this scenario, U1 and U2 are in different private namespaces and
   they enter a dialog through a proxy P1, which acts as a gateway
   between the namespaces.

      U1->P1->U2

Top      Up      ToC       Page 122 
   U1 sends:

      INVITE sip:callee@gateway.leftprivatespace.com SIP/2.0
      Contact: <sip:caller@u1.leftprivatespace.com>

   P1 uses its location service and sends the following to U2:

      INVITE sip:callee@rightprivatespace.com SIP/2.0
      Contact: <sip:caller@u1.leftprivatespace.com>
      Record-Route: <sip:gateway.rightprivatespace.com;lr>

   U2 sends this 200 (OK) back to P1:

      SIP/2.0 200 OK
      Contact: <sip:callee@u2.rightprivatespace.com>
      Record-Route: <sip:gateway.rightprivatespace.com;lr>

   P1 rewrites its Record-Route header parameter to provide a value that
   U1 will find useful, and sends the following to U1:

      SIP/2.0 200 OK
      Contact: <sip:callee@u2.rightprivatespace.com>
      Record-Route: <sip:gateway.leftprivatespace.com;lr>

   Later, U1 sends the following BYE request to P1:

      BYE sip:callee@u2.rightprivatespace.com SIP/2.0
      Route: <sip:gateway.leftprivatespace.com;lr>

   which P1 forwards to U2 as:

      BYE sip:callee@u2.rightprivatespace.com SIP/2.0



(page 122 continued on part 7)

Next RFC Part