\newif\ifmulticast
\global\multicasttrue

\section{Proxy Behavior}
\label{sec:proxy}

\subsection{Overview}
\label{sec:proxy-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
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~\ref{sec:general:req-process}. 

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 {\SHOULDNOT}
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.

\subsection{Stateful Proxy}
\label{sec:proxy-stateful}

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~\ref{sec:transactions}.  A stateful
proxy has a server transaction associated with one or more client
transactions by a higher layer proxy processing component (see
figure~\ref{fig:statefulproxymodel}), known as a proxy core.  An
incoming request is processed by a server 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~\ref{sec:transactions}. 
\begin{changebar}
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~\ref{sec:general:serv-resp}. Thus, a stateful proxy 
{\SHOULDNOT} generate 100 Trying responses to non-{\INVITE} requests.
\end{changebar}

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.

\txtpsfigsize{!}{!}{statefulproxymodel}{Stateful Proxy Model}
 
For all new requests, including any with unknown methods, an element
intending to proxy the request {\MUST}:

\begin{enumerate} 
\item{Validate the request}
(Section~\ref{sec:proxy-request-validation}) 
\begin{changebar}
\item{Preprocess routing information}
(Section~\ref{sec:proxy-request-preprocess})
\item{Determine target(s) for the request} 
(Section~\ref{sec:proxy-determine-targets}) 
\item{Forward the request to each target}
(Section~\ref{sec:proxy-request-forwarding}) 
\item{Process all responses} 
(Section~\ref{sec:proxy-response-processing}) 
\end{changebar}
\end{enumerate}

\subsection{Request Validation}
\label{sec:proxy-request-validation}

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

\begin{enumerate} 
\item Reasonable Syntax 
\begin{changebar}
\item URI scheme 
\end{changebar}
\item Max-Forwards
\item (Optional) Loop Detection
\item Proxy-Require 
\item Proxy-Authorization
\end{enumerate}

If any of these checks fail, the element {\MUST} behave as a user agent
server (see Section~\ref{sec:general:req-process}) and respond with an
error code.

Notice that a proxy is not required to detect merged
requests and {\MUSTNOT} treat merged requests as an error condition. 
The endpoints receiving the requests will resolve the merge as described
in Section~\ref{sec:general:req-process:header:merge}.  

\begin{enumerate}

\item 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
\begin{changebar}
forwarded.   For instance, an element would not reject
a request because of a malformed \header{Date} header field. 
Likewise, a proxy would not remove a malformed
\end{changebar}
\header{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 {\MUSTNOT} refuse
to proxy a request because it contains a method or header field it does
not know about.

\begin{changebar}
\item URI scheme check

If the \header{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.  
\end{changebar}

\item Max-Forwards check

The \header{Max-Forwards} header field (Section~\ref{sec:Max-Forwards}) is
used to limit the number of elements a SIP request can traverse.

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

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

If the request contains a \header{Max-Forwards} header field with a
field value of zero (0), the element {\MUSTNOT} forward the request.  If
the request was for {\OPTIONS}, the element {\MAY} act as the final
recipient and respond per Section~\ref{sec:query-for-capabilities}. 
Otherwise, the element {\MUST} return a 483 (Too many hops) response. 

\item Optional Loop Detection check
\label{sec:loop-detection}

An element {\MAY} check for forwarding loops before forwarding a
request.  If the request contains a \header{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 \header{branch} parameter calculation described in
Step~\ref{sec:proxy-request-processing-via} of 
Section~\ref{sec:proxy-request-forwarding} on this message and compare it to the
parameter received in that \header{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.

\item Proxy-Require check

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

If the request contains a \header{Proxy-Require} header field
(Section~\ref{sec:Proxy-Require}) 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
\header{Unsupported} (Section~\ref{sec:Unsupported}) header field
listing those option-tags the element did not understand.

\item Proxy-Authorization check

If an element requires credentials before forwarding a request, the
request {\MUST} be inspected as described in
Section~\ref{sec:security:auth:p2u}.  That section also defines what the
element must do if the inspection fails.

\end{enumerate}

\begin{changebar}
\subsection{Route Information Preprocessing}
\label{sec:proxy-request-preprocess}

The proxy {\MUST} inspect the \header{Request-URI} of the request.
If the \header{Request-URI} of the request contains a value this 
proxy previously placed into a \header{Record-Route} header field
(see 
Section~\ref{sec:proxy-request-forwarding} 
item~\ref{sec:proxy-request-processing-record-route}),
the proxy {\MUST} replace the \header{Request-URI} in the request
with the last value from the \header{Route} header field, and
remove that value from the \header{Route} header field. The proxy
{\MUST} then proceed as if it received this modified request. 

\motivation{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 \header{Request-URI} through strict-routing proxies
(see Section~\ref{sec:dialog:uac:generate}).}

\motivation{This requirement does not obligate a proxy to keep state
in order to detect URIs it previously placed in \header{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
\header{Request-URI} contains an \header{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 \header{Request-URI} has an 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
\header{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.   

\motivation{A request may arrive with an \header{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 \header{Route} header field indicates this
proxy, the proxy {\MUST} remove that value from the request. 


\subsection{Determining request targets}
\label{sec:proxy-determine-targets}

\end{changebar}

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
\header{Request-URI} of the request contains an \header{maddr} parameter, 
the \header{Request-URI} {\MUST} be placed into the target set as the
only target URI, and the proxy {\MUST} proceed to 
Section~\ref{sec:proxy-request-forwarding}. 


If the domain of the \header{Request-URI} indicates a domain this
element is not responsible for, the
\header{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~\ref{sec:proxy-request-forwarding}).

\motivation{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 \header{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 \header{Request-URI}.
 When accessing
the location service constructed by a registrar, the
\header{Request-URI} {\MUST} first be canonicalized as described in
Section~\ref{sec:reg:processing} before being used as an index.
 The output of
these mechanisms is used to construct the target set. 

If the \header{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 \header{Contact} header field containing URIs of new addresses
to be tried.  For example, an {\INVITE} to 
sip:John.Smith@company.com may be ambiguous at a proxy whose location
service has multiple John Smiths listed.  See 
Section~\ref{sec:response-codes:485} 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 {\MUSTNOT} be added again.

\begin{changebar}
A proxy {\MUSTNOT} add additional targets to the target set if the
\header{Request-URI} of the original request does not indicate a
resource this proxy is responsible for.

\motivation{A proxy can only change the \header{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 \header{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
\end{changebar}
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
{\MUSTNOT} be added to the set more than once. 

\motivation{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 forwarding of 
Section~\ref{sec:proxy-request-forwarding}, 
Item~\ref{sec:proxy-request-processing:route}, 
the identity of that next hop,
expressed as a SIP or SIPS URI, is inserted as the top-most 
\header{Route} header field value into the request.


If the \header{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.

\subsection{Request Forwarding}
\label{sec:proxy-request-processing}
\label{sec:proxy-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~\ref{sec:Contact}).  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:

\begin{enumerate} 
\item Make a copy of the received request 
\item Update the Request-URI 
\begin{changebar}
\item Update the Max-Forwards header field 
\item Optionally add a Record-route header field value 
\item Optionally add additional header fields 
\item Postprocess routing information
\item Determine the next-hop address, port, and transport
\item Add a Via header field value
\item Add a Content-Length header field if necessary
\item Forward the new request 
\end{changebar}
\item Set timer C
\end{enumerate}

Each of these steps is detailed below:

\begin{enumerate}

\item Copy request

\begin{changebar}
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 {\MUSTNOT}
be removed.
The copy {\SHOULD} maintain the ordering of the header fields
as in the received request.  The proxy {\MUSTNOT} reorder field values
with a common field name (See Section~\ref{sec:header-format}).
The proxy {\MUSTNOT} add to, modify, or remove the message body.
\end{changebar}

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

\item Request-URI

The \header{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 \header{Request-URI} is placed
into the target set without being modified. For that target,
the replacement above is effectively a no-op.

\item \header{Max-Forwards}


If the copy contains a \header{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.

\motivation{Some existing UAs will not provide a \header{Max-Forwards}
header field in a request.}


\item Record-Route \label{sec:proxy-request-processing-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
\header{Record-Route} header field value into the copy before any existing
\header{Record-Route} header field values, even if a \header{Route} header field is
already present.

\motivation{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 \header{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~\ref{sec:dialog} these \header{Record-Route} header
field values will not have any effect on the route sets used by the
endpoints.

\motivation{The proxy will remain on the path if it chooses to not insert
a \header{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 \header{Record-Route} header field value into any
request.  If the request does not initiate a dialog, the endpoints will
ignore the value.  See Section~\ref{sec:dialog} for details on how
endpoints use the \header{Record-Route} header field values to construct
\header{Route} header fields. 

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

The URI placed in the \header{Record-Route} header field value {\MUST}
be a SIP URI.  This URI {\MUST} contain an \header{lr} parameter (see
Section~\ref{sec:sip-uri-components}).  This URI {\MAY} be different for
each destination the request is forwarded to.  The URI {\SHOULDNOT}
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.

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

The URI placed in the \header{Record-Route} header field {\MUST} resolve
to the element inserting it (or a suitable stand-in) when the server
location procedures of~\citenorm{draft-ietf-sip-srv} are applied to it, so
that subsequent requests reach the same SIP element. \begin{changebar}
If the \header{Request-URI} contains a SIPS URI, 
or the topmost \header{Route} header field (after the post processing of bullet \ref{sec:proxy-request-processing:route} contains a SIPS URI, the URI placed
into the \header{Record-Route} header field {\MUST} be a SIPS URI.
Furthermore, if the request was not received over TLS, the proxy {\MUST}
insert a \header{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 \header{Request-URI} or topmost \header{Record-Route} header field
value, {\MUST} insert a \header{Record-Route} header field that is not a SIPS
URI.

\motivation{A proxy at a security perimeter must remain on the perimeter 
throughout the dialog.}

\end{changebar}

If the URI placed in the \header{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 \header{Record-Route} header
field value being added). 
Item~\ref{sec:proxy-response-processing-record-route} of
Section~\ref{sec:proxy-response-processing} recommends a mechanism to
make the URI sufficiently distinct.

The proxy {\MAY} include parameters in the \header{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 \header{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 \header{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
\header{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
{\MUSTNOT} use a URI obtained from a \header{Record-Route} header field
outside the dialog in which it was provided.  See
Section~\ref{sec:dialog} for more information on an endpoint's use of
\header{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 \header{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.

\item Add Additional Header Fields

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

\begin{changebar}
\item \header{Postprocess routing information}
\label{sec:proxy-request-processing:route}

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
\header{lr} parameter). This set {\MUST} be pushed into the
\header{Route} header field of the copy ahead of any existing values, if
present. If the \header{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 \header{Route} value
into the \header{Route} header field is to bypass the forwarding logic
of item~\ref{sec:proxy-request-processing:forward} below, and instead
just send the request to the address, port, and transport for that
specific proxy. If the request has a \header{Route} header field, 
this alternative {\MUSTNOT}
be used unless it is known that next hop proxy is a loose
router. Otherwise, this approach {\MAY} be used, but the
\header{Route} insertion mechanism above is preferred for its
robustness, flexibility, generality and consistency of operation.
\begin{changebar} Furthermore, if the \header{Request-URI} contains
a SIPS URI, TLS {\MUST} be used to communicate with that proxy.
\end{changebar}

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

\begin{itemize}
\item The proxy {\MUST} place the \header{Request-URI} 
into the \header{Route} header field as the last value.

\item The proxy {\MUST} then place the first \header{Route}
header field value into the \header{Request-URI} and remove
that value from the \header{Route} header field.
\end{itemize}

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

\begin{changebar}
\item Determine Next-Hop Address, Port, and Transport
\label{sec:proxy-determine-next-hop}

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 \header{Route}
and \header{Request-URI}. Such a policy {\MUSTNOT} 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
{\NOTRECOMMENDED}; instead a \header{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~\citenorm{draft-ietf-sip-srv} 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~\ref{sec:proxy-request-processing:route} above, the proxy {\MUST}
apply those procedures to the \header{Request-URI} of the request. 
Otherwise, the proxy {\MUST} apply the procedures to the first value in
the \header{Route} header field, if present, else the
\header{Request-URI}.  The procedures will produce an ordered set of
(address, port, transport) tuples. \begin{changebar} Independently of which URI
is being used as input to the procedures of \cite{draft-ietf-sip-srv},
if the \header{Request-URI} specifies a SIPS resource, the proxy {\MUST}
follow the procedures of \cite{draft-ietf-sip-srv} as if the input URI were
a SIPS URI. \end{changebar}

As described in~\citenorm{draft-ietf-sip-srv}, 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~\ref{sec:proxy-request-processing-via}
through~\ref{sec:proxy-request-processing:forward}.  Since each attempt
uses a new client transaction, it represents a new branch.  Thus, the
branch parameter provided with the \header{Via} header field inserted in
step~\ref{sec:proxy-request-processing-via} {\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. 

\item Add a Via header field value
\label{sec:proxy-request-processing-via}

The proxy {\MUST} insert a \header{Via} header field value
into the copy before the existing \header{Via} header field values.  The
construction of this value follows the same guidelines of 
Section~\ref{sec:general:uac:header:via}.  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. 

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~\ref{sec:general:uac:header:via} 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 \header{branch}
parameter {\SHOULD} reflect all of those fields (including any
\header{Route}, \header{Proxy-Require} and \header{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 (Section~\ref{sec:proxy-request-validation} \begin{changebar}
A common way to create this value is to compute a cryptographic hash of
the \header{To} tag, \header{From} tag, \header{Call-ID} header field,
the \header{Request-URI} of the request received (before translation)
and the sequence number from the \header{CSeq} header field, in addition
to any \header{Proxy-Require} and \header{Proxy-Authorization} header
fields that may be present.  \end{changebar} The algorithm used to
compute the hash is implementation-dependent, but MD5 
(RFC~1321~\citenonnorm{rfc1321}), expressed in hexadecimal, is a reasonable
choice.  (Base64 is not permissible for a \header{token}.)

\motivation{If a proxy wishes to detect
loops, the ``\header{branch}'' parameter it supplies {\MUST} depend on
all information affecting processing of a
request, including the incoming \header{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 {\MUSTNOT} be included in the calculation of the
\header{branch} parameter.  In particular, {\CANCEL} and {\ACK} requests
(for non-2xx responses) {\MUST} have the same \header{branch} value as
the corresponding request they cancel or acknowledge.  The
\header{branch} parameter is used in correlating those requests at the
server handling them (see
Sections~\ref{sec:transactions:server:match}~and~\ref{sec:canceluas}).

\item 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 \header{Content-Length} header
field, the proxy {\MUST} insert one with the correct value for
the body of the request
(see Section~\ref{sec:Content-Length}).

\item Forward Request
\label{sec:proxy-request-processing:forward}

A stateful proxy {\MUST} create a new client transaction for this request as
described in Section~\ref{sec:transactions:client} and instructs
the transaction to send the request using the address, port and
transport determined in 
step~\ref{sec:proxy-determine-next-hop}.
\end{changebar}

\item Set timer C
\label{sec:proxy-request-processing:timerc}


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~\ref{sec:proxy-response-processing}
bullet~\ref{sec:proxy-response-processing-timerc} discusses how this timer is
updated with provisional responses, and Section~\ref{sec:proxy-timerc}
discusses processing when it fires.


\end{enumerate}

\subsection{Response Processing}
\label{sec:proxy-response-processing}

When a response is received by an element, it first tries to locate a
client transaction (Section~\ref{sec:transactions:client:match})
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.

\motivation{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.}

As client transactions pass responses to the proxy layer, the following
processing {\MUST} take place:

\begin{enumerate} 
\item Find the appropriate response context 
\item Update timer C for provisional responses
\item Remove the topmost Via 
\item Add the response to the response context
\item Check to see if this response should be forwarded immediately

\item 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.

\item Aggregate authorization header field values if necessary

\item Optionally rewrite Record-Route header field values

\item Forward the response

\item Generate any necessary {\CANCEL} requests

\end{enumerate}


Each of the above steps are detailed below:

\begin{enumerate}

\item Find Context

The proxy locates the ``response context'' it created before forwarding
the original request using the key described in
Section~\ref{sec:proxy-request-forwarding}.  The remaining processing
steps take place in this context.


\item Update timer C for provisional responses
\label{sec:proxy-response-processing-timerc}

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.


\item Via \label{sec:proxy-response-processing-via}

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

If no \header{Via} header field values remain in the response, the response was
meant for this element and {\MUSTNOT} be forwarded.  The remainder of
the processing described in this section is not performed on this
message,  the UAC processing rules described in
Section~\ref{sec:general:resp-proc} are followed instead (transport
layer processing has already occurred).

This will happen, for instance, when the element
generates {\CANCEL} requests as described in
Section~\ref{sec:proxy-response-processing-cancel}. 

\item Add response to context
\label{sec:proxy-response-processing-add-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.  \begin{changebar} However, a proxy {\SHOULDNOT} recurse to a non-SIPS
URI if the \header{Request-URI} of the original request was a SIPS URI. 
\end{changebar} If the proxy recurses on all of the contacts in a 3xx
response, the proxy {\SHOULDNOT} add the resulting contactless response
to the response context.

\motivation{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 \header{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~\ref{sec:uri-telephone-subscriber} 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 {\SHOULDNOT} be added to the
response context.

\item Check response for forwarding

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

\begin{itemize}
\item Any provisional response other than 100 (Trying) 

\item Any 2xx response
\end{itemize}

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~\ref{sec:proxy-response-processing-cancel}, \begin{changebar} and it {\MUSTNOT} 
create any new branches in this context. \end{changebar}

\motivation{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 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:  \begin{itemize}
\item Any 2xx response to an {\INVITE} request \end{itemize}

A stateful proxy {\MUSTNOT} immediately forward any other responses.  In
particular, a stateful proxy {\MUSTNOT} 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. 


\item 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.

\begin{changebar}
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} 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.
\end{changebar}

A proxy which receives a 503 (Service Unavailable) response {\SHOULDNOT}
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 \header{Request-URI} in the request which generated the
503.

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 {\MUSTNOT} insert a tag into the \header{To}
header field of a 1xx or 2xx response if the request did not contain
one.  A proxy {\MUSTNOT} modify the tag in the \header{To} header field of a 1xx or 2xx
 response.

Since a proxy may not insert a tag into the \header{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-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 {\MUSTNOT} modify the To tag in any forwarded response to a
request that contains a To tag.

\motivation{ 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.}



\item Aggregate Authorization Header Field Values
\label{sec:proxy-response-processing-aggregate-headers}

If the selected response is a 401 (Unauthorized) or 407 (Proxy
Authentication Required), the proxy {\MUST} collect any
\header{WWW-Authenticate} and \header{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 \header{WWW-Authenticate} AND \header{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~\ref{sec:security}.

\item Record-Route \label{sec:proxy-response-processing-record-route}

If the selected response contains a \header{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.

\begin{changebar}
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 
\header{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 \header{Record-Route}
header field to be a SIP URI.
\end{changebar}

The new URI provided by the proxy {\MUST} satisfy the same constraints
on URIs placed in \header{Record-Route} header fields in requests
(see
Step~\ref{sec:proxy-request-processing-record-route} of 
Section~\ref{sec:proxy-request-forwarding})  with the following
modifications:

The URI {\SHOULDNOT} 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 \header{Record-Route} header field in
the response, one of the operations it performs is locating the
\header{Record-Route} value that it had inserted.  If the request spiraled,
and the proxy inserted a \header{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 \header{Record-Route} header
field values insert sufficiently distinct URIs into the
\header{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
\header{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 \header{Record-Route} header field value with the parameter) will
correctly extract the next \header{Record-Route} header field value inserted by that
proxy.

\begin{changebar}
\motivation{
Not every response to a request to which a proxy adds a \header{Record-Route}
header field value will contain a \header{Record-Route} header field. If the
response does contain a \header{Record-Route} header field, it will contain
the value the proxy added.
}
\end{changebar}

\item 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.
\begin{changebar}
The proxy {\MUSTNOT} add to, modify, or remove the message body.
 Unless
otherwise specified, the proxy {\MUSTNOT} remove any
header field values other than the \header{Via} header field value discussed in
Section~\ref{sec:proxy-response-processing}
Item~\ref{sec:proxy-response-processing-via}.
\end{changebar}
In particular, the
proxy {\MUSTNOT} remove any ``received'' parameter it may have added to
the next \header{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 \header{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.  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.  

\item Generate {\CANCEL}s \label{sec:proxy-response-processing-cancel}

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~\ref{sec:canceluac}.

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. 

\end{enumerate}

\subsection{Processing Timer C}
\label{sec:proxy-timerc}

If timer C should fire, the proxy {\MUST} either reset the timer with
any value it chooses, or 
\begin{changebar}
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.

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. 
\end{changebar}

\subsection{Handling Transport Errors}
\label{sec:proxy-transport-errors}

If the transport layer notifies a proxy of an error when it tries to
forward a request (see Section~\ref{sec:transport:error}), the proxy
{\MUST} behave as if the forwarded request received a 400 (Bad Request)
response. 

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

\motivation{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.}

\subsection{{\CANCEL} Processing}
\label{sec:proxy-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~\ref{sec:canceluac}).  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 \header{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~\ref{sec:general:req-process}.  Furthermore, the element {\MUST}
generate {\CANCEL} requests for all pending client transactions in the
context as described in
Section~\ref{sec:proxy-response-processing}
step~\ref{sec:proxy-response-processing-cancel}.

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

\subsection{Stateless Proxy}
\label{sec:proxy-stateless}

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~\ref{sec:transport}).  As a
result, stateless proxies do not retransmit messages on their own.  They
do, however, forward all retransmission they receive (they do not have
the ability to distinguish a retransmission from the original message). 
Furthermore, when handling a request statelessly, an element {\MUSTNOT}
generate its own 100 (Trying) or any other provisional response.

A stateless proxy {\MUST} validate a request as described in 
Section~\ref{sec:proxy-request-validation}

A stateless proxy {\MUST} follow the request processing steps
described in
Sections~\ref{sec:proxy-request-preprocess} 
through~\ref{sec:proxy-determine-targets}
with the following
exception:
\begin{itemize}
\item 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}.
\end{itemize}

A stateless proxy {\MUST} follow the request processing steps 
described in Section~\ref{sec:proxy-request-forwarding} with the
following exceptions:
\begin{itemize}
\item

\begin{changebar} The requirement for unique branch IDs across space and time applies to stateless
proxies as well. \end{changebar} However, a stateless proxy cannot simply use a random
number generator to compute the first component of the branch ID, as
described in Section~\ref{sec:proxy-request-forwarding} 
bullet~\ref{sec:proxy-request-processing-via}.  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 \header{branch} parameter {\MUST} be computed as a
combinatoric function of message parameters which are invariant on
retransmission.

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 \header{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 \header{Via}, \begin{changebar} the tag in the \header{To} header field, the tag in the \header{From} header field, \end{changebar} the \header{Call-ID} header field, the \header{CSeq} number (but not method), and the \header{Request-URI} from the received request.  One of these fields will always vary across two different transactions.

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

\item A stateless proxy determines where to forward the request as described
for stateful proxies in 
Section~\ref{sec:proxy-request-forwarding}
Item~\ref{sec:proxy-request-processing:forward}.
The request is sent directly to the transport layer instead of
through a client transaction.  
\end{changebar}

\end{itemize}

\motivation{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 {\MUSTNOT} 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 \header{Route} header field
processing to {\CANCEL} requests that it applies to any other request.

Response processing as described in
Section~\ref{sec:proxy-response-processing} does not apply to a proxy
behaving statelessly.  When a response arrives at a stateless proxy, the
\begin{changebar}
proxy {\MUST} inspect the sent-by value in the first (topmost) \header{Via}
\end{changebar}
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 \header{Via} header field value. 
\begin{changebar}
The proxy {\MUSTNOT} add to, modify, or remove the message body.
Unless specified otherwise, the
proxy {\MUSTNOT} remove any other header field values.  If
the address does not match the proxy, the message {\MUST} be silently
discarded.
\end{changebar}

\subsection{Summary of Proxy Route Processing}
\label{sec:proxy:route-processing}

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

\begin{enumerate}

\item The proxy will inspect the \header{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
\header{Request-URI}.

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

\item The proxy will forward the request to the resource indicated by
the URI in the topmost \header{Route} header field value or in
the \header{Request-URI} if no \header{Route} header field is present. The
proxy determines the address, port and transport to use when forwarding the
request by applying the procedures in~\citenorm{draft-ietf-sip-srv} to that
URI.

\end{enumerate}

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

\subsubsection{Examples}

\label{sec:proxy-record-route-example}

\paragraph{Basic SIP Trapezoid}

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

U1 sends:

\begin{verbatim}
INVITE sip:callee@domain.com SIP/2.0
Contact: sip:caller@u1.example.com
\end{verbatim}

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
\header{Record-Route} header field value:

\begin{verbatim}
INVITE sip:callee@domain.com SIP/2.0
Contact: sip:caller@u1.example.com
Record-Route: <sip:p1.example.com;lr>
\end{verbatim}

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

\begin{verbatim}
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>
\end{verbatim}

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

\begin{verbatim}
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>
\end{verbatim}

The callee at u2 also sets its dialog state's remote target URI
to sip:caller@u1.example.com and its route set to
\begin{verbatim}
(<sip:p2.domain.com;lr>,<sip:p1.example.com;lr>)
\end{verbatim}

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 
\begin{verbatim}
(<sip:p1.example.com;lr>,<sip:p2.domain.com;lr>)
\end{verbatim}

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

\begin{verbatim}
BYE sip:callee@u2.domain.com SIP/2.0
Route: <sip:p1.example.com;lr>,<sip:p2.domain.com;lr>
\end{verbatim}

As any other element (including proxies) would do, it 
resolves the URI in the topmost \header{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 \header{Request-URI} so it doesn't change it.
It does see that it is the first value in the \header{Route}
header field, so it removes that value, and forwards the request
to P2:

\begin{verbatim}
BYE sip:callee@u2.domain.com SIP/2.0
Route: <sip:p2.domain.com;lr>
\end{verbatim}

P2 also notices it is not responsible for the resource indicated
by the \header{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 \header{Route} header field value, so it removes it and forwards
the following to u2.domain.com based on a DNS lookup against the
\header{Request-URI}:

\begin{verbatim}
BYE sip:callee@u2.domain.com SIP/2.0
\end{verbatim}

\paragraph{Traversing a strict-routing proxy}

In this scenario, a dialog is established across four proxies,
each of which adds \header{Record-Route} header field values.
The third proxy implements the strict-routing procedures
specified in RFC~2543 and the bis drafts up to bis-05.

\begin{verbatim}
U1->P1->P2->P3->P4->U2
\end{verbatim}

The INVITE arriving at U2 contains
\begin{verbatim}
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>
\end{verbatim}

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

\begin{verbatim}
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>
\end{verbatim}

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

\begin{verbatim}
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>
\end{verbatim}

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

\begin{verbatim}
BYE sip:p2.example.com;lr SIP/2.0
Route: <sip:p1.example.com;lr>
Route: <sip:caller@u1.example.com>
\end{verbatim}

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

\begin{verbatim}
BYE sip:caller@u1.example.com SIP/2.0
Route: <sip:p1.example.com;lr>
\end{verbatim}

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

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

\begin{verbatim}
BYE sip:caller@u1.example.com SIP/2.0
\end{verbatim}

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


\paragraph{Rewriting \header{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. 

\begin{verbatim}
U1->P1->U2
\end{verbatim}

U1 sends:

\begin{verbatim}
INVITE sip:callee@gateway.leftprivatespace.com SIP/2.0
Contact: <sip:caller@u1.leftprivatespace.com>
\end{verbatim}

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

\begin{verbatim}
INVITE sip:callee@rightprivatespace.com SIP/2.0
Contact: <sip:caller@u1.leftprivatespace.com>
Record-Route: <sip:gateway.rightprivatespace.com;lr>
\end{verbatim}

U2 sends this 200 (OK) back to PI:

\begin{verbatim}
SIP/2.0 200 OK
Contact: <sip:callee@u2.rightprivatespace.com>
Record-Route: <sip:gateway.rightprivatespace.com;lr>
\end{verbatim}

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

\begin{verbatim}
SIP/2.0 200 OK
Contact: <sip:callee@u2.rightprivatespace.com>
Record-Route: <sip:gateway.leftprivatespace.com;lr>
\end{verbatim}

Later, U1 sends the following {\BYE} request to P1:

\begin{verbatim}
BYE sip:callee@u2.rightprivatespace.com SIP/2.0
Route: <sip:gateway.leftprivatespace.com;lr>
\end{verbatim}

which P1 forwards to U2 as

\begin{verbatim}
BYE sip:callee@u2.rightprivatespace.com SIP/2.0
\end{verbatim}
