[asterisk-dev] [Code Review] Properly route responses according to the Via headers in the request

Alex Hermann alex at speakup.nl
Thu Dec 23 14:47:05 UTC 2010

On Thursday 23 December 2010, Olle E. Johansson wrote:
> 23 dec 2010 kl. 09.48 skrev Alex Hermann:
> > On Thursday 23 December 2010, Olle E Johansson wrote:
> >>> On 2010-12-23 02:11:36, Olle E Johansson wrote:
> >>>> A UAC should always respond
> >>>> to the sender's IP address and port.
> > 
> > Wrong, only to the address, the port is taken form the Via header
> > unless rport is used.
> Please read the RFC.
Let's ignore that.

> >>>> If you make the nat=yes behaviour for
> >>>> SIP the default, you are right on. Via headers are used for proxies,
> >>>> since a proxy do not have to keep state and remember the sender. The
> >>>> proxy handling the response might not even be the same as the one
> >>>> processing the request.
> > 
> > Wrong, replies always follow the exact same path back along proxies as
> > the request has followed on its way to the UAS.
> No.
Now that's a helpful reply, please show where/when this is not the case.

The whole section 18.2 is written to do exactly the above (for UDP):

1) Hostnames in the Via sent-by are overruled by the address the request is 
received from (received parameter)
2) A Via sent-by address different from the received address is overruled by 
received address.
3) Same for portnumber if rfc3581 is used and rport is present. Otherwise, 
the port number from the Via's sent-by value is used, NOT the port the 
request was received from.

Every hop in the SIP path does this, so that responses are routed through 
exactly the same hops as the request but in reverse order.

> >>>> Via headers is not for UA's unless you have
> >>>> a transport machine that adds  an Via header when receiving the
> >>>> packet and delivers it up to the the transaction layer. If that's
> >>>> the case, the transaction layer routes the response to the top via
> >>>> header, added by the incoming transport. Since we have none of that,
> >>>> we just respond to the sender. Period.
> >> 
> >> I haven't figured out from your e-mails whether or not you had a route
> >> set. If you had a route set from the initial transaction and get the
> >> INFO from another address, we need to figure out what to do.
> >> 
> >> If there's no route set (no proxy added a record-route header to
> >> request to stay in the signalling path) then only the initial
> >> transaction goes through the proxy and we should respond directly to
> >> the device.
> > 
> > For replying to a request, it is completely irrelevant if there is a
> > proxy in the path or whether is is statefull, stateless, has or has
> > not record- route headers.
> You totally do not understand or do not want to read what I wrote.
> This part was not about responses, but about the INFO that was sent
> directly. Please be more careful before you respond.

Well you mentioned "respond directly". I was just noting that it doesn't 
matter how the request arrived at the UAS, only from where. The process for 
selecting the address and port for sending the reply to is identical for 
every request (transaction). In fact, every transaction can arrive from 
different IP's (load-balanced proxies for example). Asterisk just must not 
store the address on the first request and use that blindly for every other 
transaction in the dialog but do section 18.2 procedures for _every_ 
transaction it receives.

> > Your last 2 emails only add to the confusion as they contradict the
> > rfc's.
> The same to you. Let's try to clear this up.
> > Proper reply behaviour is described in 18.2 of rfc3261 and rfc3581 and
> > is certainly no rocket-science. Short versions have already been
> > mailed in this thread.
> But the wrong quotes.
Please quote the correct parts then.

Here is my "interpretation", please indicate where my earlier statements 
about sending responses are against tje rfc's.

> RFC3261

> 18.2 Servers
> 18.2.1 Receiving Requests


>    When the server transport receives a request over any transport, it
>    MUST examine the value of the "sent-by" parameter in the top Via
>    header field value.  If the host portion of the "sent-by" parameter
>    contains a domain name, or if it contains an IP address that differs
>    from the packet source address, the server MUST add a "received"
>    parameter to that Via header field value.  This parameter MUST
>    contain the source address from which the packet was received.

Here a domain name or an address different from the received addres in sent-
by is overruled by the received address. Responses are sent tot the received 

Note that the port is unaffected.

>    This
>    is to assist the server transport layer in sending the response,
>    since it must be sent to the source IP address from which the request
>    came.


> 18.2.2 Sending Responses
>    The server transport uses the value of the top Via header field in
>    order to determine where to send a response.  It MUST follow the
>    following process:

<snip, let's focus on UDP for now, as the patch was for Asterisk 1.4>

>       o  Otherwise, if the Via header field value contains a "maddr"
>          parameter, the response MUST be forwarded to the address listed
>          there, using the port indicated in "sent-by", or port 5060 if
>          none is present.  If the address is a multicast address, the
>          response SHOULD be sent using the TTL indicated in the "ttl"
>          parameter, or with a TTL of 1 if that parameter is not present.

maddr overrules sent-by, so response go to maddr address if present (port 
from sent-by).

>       o  Otherwise (for unreliable unicast transports), if the top Via
>          has a "received" parameter, the response MUST be sent to the
>          address in the "received" parameter, using the port indicated
>          in the "sent-by" value, or using port 5060 if none is specified
>          explicitly.  If this fails, for example, elicits an ICMP "port
>          unreachable" response, the procedures of Section 5 of [4]
>          SHOULD be used to determine where to send the response.

Irthe procedures form section 18.2.1 added a received parameter (in Asterisk 
this won't be done due to lack of a transaction layer, but it should still 
follow this paragraph if sent-by address != received address) the response 
is sent to the received address (and port from Via's sent-by parameter).

>       o  Otherwise, if it is not receiver-tagged, the response MUST be
>          sent to the address indicated by the "sent-by" value, using the
>          procedures in Section 5 of [4].
This already implies the sent-by is not different from received address and 
thus the response is ultimately sent to the received address (and port).

> RFC3581
> 4.  Server Behavior
>    The server behavior specified here affects the transport processing
>    defined in Section 18.2 of SIP [1].
>    When a server compliant to this specification (which can be a proxy
>    or UAS) receives a request, it examines the topmost Via header field
>    value.  If this Via header field value contains an "rport" parameter
>    with no value, it MUST set the value of the parameter to the source
>    port of the request.  This is analogous to the way in which a server
>    will insert the "received" parameter into the topmost Via header
>    field value.  In fact, the server MUST insert a "received" parameter
>    containing the source IP address that the request came from, even if
>    it is identical to the value of the "sent-by" component.  Note that
>    this processing takes place independent of the transport protocol.

Adding the received parameter is made mandatory here. In addition, the port 
from which the request is received is stored (rport).

>    When a server attempts to send a response, it examines the topmost
>    Via header field value of that response.  If the "sent-protocol"
>    component indicates an unreliable unicast transport protocol, such as
>    UDP, and there is no "maddr" parameter, but there is both a
>    "received" parameter and an "rport" parameter, the response MUST be
>    sent to the IP address listed in the "received" parameter, and the
>    port in the "rport" parameter.  The response MUST be sent from the
>    same address and port that the corresponding request was received on.
>    This effectively adds a new processing step between bullets two and
>    three in Section 18.2.2 of SIP [1].

Here the port number in the sent-by is overruled by the rport. Responses are 
effectively sent to the address AND port from which the request was 


Alex Hermann

More information about the asterisk-dev mailing list