In the last post we have seen a basic SIP (VoLTE) session. This time we should analyze in more detail, what headers are used by network elements for their routing decisions and how they discover what port and IP to use. In practice that’s what people are not always sure about. They know the flow, order of signalling messages, but when something goes wrong, they are just guessing what could be the reason.

SIP Message Routing
Let’s recap what we have learnt so far. We use loose routing. So if a SIP message contains a Route header, we will use the top most one for the routing. If there is no Route header the routing is done based on the Request-URI, which contains the address of the final recipient. Don’t forget, network elements are able to add and modify the headers. The way how we handle the messages and modify their content within the IMS is described in 3GPP standards.
We will go once again through the routing of the original SIP INVITE message. We can take a closer look on what are the SIP headers used for the routing in IMS.
Please note, the flow is simplified and the particular values are used just for an illustration. The flow and headers differ operator to operator. Still we can see, that from a great part the routing is done based on the Route header. The information where to route SIP INVITE message to was pre-shared during the Registration (Service-Route, Contact) and Third Party Registration (Contact header sent by TAS). The R-URI is analyzed firstly by O-TAS, which can apply normalization, translations, can trigger to ENUM server, etc. Triggering to ENUM can be done also by S-CSCF before it tries to deliver the SIP INVITE to a terminating IMS. Routing towards I-CSCF is done based on the content of the R-URI.
In the terminating phase, firstly the I-CSCF locates the right S-CSCF using LIR/LIA diameter messages. SIP routing is usually done internally within IMS Core, otherwise a Route header pointing to S-CSCF would be used. Then the S-CSCF sends the message to a T-TAS.
How does the TAS knows whether to apply originating or terminating services? The information is inserted in the SIP messages by S-CSCF, which knows from where the message comes. If it comes from A-SBC, we apply originating services and an ‘orig’ tag is inserted in the TAS Route header. If the message comes from I-CSCF, the S-CSCF doesn’t add the ‘orig; tag, so TAS is applying terminating services.
Route: <sip:tas1.ims.operator.com;orig;transport=udp;lr>
When the T-TAS is finished, it sends the message back using a Route header inserted previously by the S-CSCF, S-CSCF then modifies the R-URI (Contact header from Registration) and forwards to SBC using a Route header (Path from Registration).

SIP INVITE on IMS Core
Responses
Routing of responses is very simple, we simply follow the Via headers.

SIP Via header – Response routing
When a client creates a request, it inserts a Via into that request. The protocol name and protocol version is always SIP and 2.0. The Via header field value also contains a branch parameter, which identifies the transaction created by that request. The branch parameter is used by both the client and the server. Each proxy on the path then firstly determines (e.g. using DNS) the next hop (including the transport layer!) and inserts itself into Via headers.
SIP/2.0 183 Session Progress Via: SIP/2.0/UDP proxy.operator.com;branch=z9hG4bKkjsh77 Via: SIP/2.0/UDP 10.0.0.1:5040;received=192.0.2.1;rport=6677;branch=z9hG4bKabcd123
The value of the Via header field contains transport, IP and a port. If the port is missing a default value is used based on the transport layer. In case the proxy is behind a NAT, the receiving network element can note down the original IP address and the original port, using received and rport tags as described in the RFC 3581.

SIP and NAT
Locating SIP Servers
But that’s just a beginning. We mentioned that already and you probably noticed that as well – before we can really send a SIP message to a next hop, we have to firstly decide, what type of transport will be used (UDP/TCP/TLS/SCTP), what port and what IP.
The rules are described in RFC 3263 and RFC 7984. If you are serious about SIP, take your time and read it. For others I’ll try to simplify.
Transport discovery
If the target (R-URI or the top most Route header) is a numeric IP, we use UDP transport layer.
sip:2233445566@10.0.0.1
If no transport is specified, but port is specified, we also use UDP.
sip:context123@scscf1.ims.operator.com:5070
Otherwise we can specify the transport directly.
sip:context123@scscf1.ims.operator.com;transport=tcp
For sips we always use TLS.
If none of the rules specified above applies, then we have to use DNS to resolve the address.
; order pref flags service regexp replacement IN NAPTR 10 50 "s" "SIPS+D2T" "" _sips._tcp.tas.ims.operator.com. IN NAPTR 20 50 "s" "SIP+D2T" "" _sip._tcp.tas.ims.operator.com. IN NAPTR 100 50 "s" "SIP+D2U" "" _sip._udp.tas.ims.operator.com.
The third column defines, what will be the order/priority. The row with the lowest value has the highest priority. In case when more rows have the same priority, then we loadshare using preference/weights in the fourth column. The flag “s” then tells to us, that the next step is the DNS SRV request. Again, for more details, please refer to RFC.
Port Discovery
It is even easier. If the port is specified, simply us it.
sip: context123@scscf1.ims.operator.com:5070
If the target is a numeric IP address, we use default ports for given transport layers.
sip:2233445566@10.0.0.1;transport=tls => port 5061 sip:2233445566@10.0.0.1;transport=tcp => port 5060 sip:2233445566@10.0.0.1;transport=udp => port 5060
Otherwise we send an SRV request to DNS.
;; Priority Weight Port Target IN SRV 0 1 5060 tas1.ims.operator.com IN SRV 0 2 5060 tas2.ims.operator.com
IP Discovery
To discover an exact IP address is just a piece of cake. Either the numeric IP is present, then we will use it.
sip:2233445566@10.0.0.1
Or, if the SRV request was already done, use the returned IP address if present. If it wasn’t present, perform A query based on that result.
tas1.ims.operator.com
If we haven’t done SRV request, then do A query using the SIP URI domain name. Use the numeric IP in the order returned by DNS.
tas1.ims.operator.com 1800 IN A 10.10.1.1 tas2.ims.operator.com 1800 IN A 10.20.1.1
Requests within a Dialog
The last time we have seen, that there can be more SIP requests sent during a session. For routing of these subsequent requests we use the same algorithm as for the original INVITE. The difference is how we set the R-URI and Route header list.
When a UAC receives a provisional response, it will take the Contact header and its value will be used as a R-URI for a subsequent request. If any of Proxies on the path want to process also subsequent messages, they insert a Record-Route header. For a new request the Record-Route values will be interested as Route header fields.

Record-Route and Contact headers
Contact and Record-Route are not limited to responses, they are used in requests too. One of the reasons is that the roles of a SIP Server/Client can change within one session (e.g. later the original UAS can send a re-INVITE or BYE message).
After all it’s no rocket science. From a proxy perspective, each network element is following a simple set of rules defined by RFC 3261.
For each target, the proxy forwards the request following these steps:
- Make a copy of the received request
- Update the Request-URI
- Update the Max-Forwards header field
- Optionally add a Record-route header field value
- Optionally add additional header fields
- Postprocess routing information
- Determine the next-hop address, port, and transport
- Add a Via header field value
- Add a Content-Length header field if necessary
- Forward the new request
- Set timer C
And for a response:
- Find the appropriate response context
- Update timer C for provisional responses
- Remove the topmost Via
- Add the response to the response context
- Check to see if this response should be forwarded immediately
- 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 is 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.
- Aggregate authorization header field values if necessary
- Optionally rewrite Record-Route header field values
- Forward the response
- Generate any necessary CANCEL requests
As you can see it is not that difficult, but still there is a lot of to learn. Perhaps the next time we can see, how to close or cancel a session.
Related posts:
As per RFC3261 only an INVITE or re-INVITE record-route list can modify future SIP Requests’ Route header lists even if Record-Route is for instance present in an in dialogue UPDATE method. However, I have the following question because I cannot find it: User Agent sending the INVITE is getting informed about the Record-Route set list in any kind of response ? Meaning, can it be both a provisional and a final response or only a final one (200 OK) ? Also, is the record-route info reaching the UE back in response or this info is stored in the P-CSCF/SBC for the corresponding session ? I am asking because in a test environment setup record-route info never reaches the UE directly and I was wondering if there is a rule for it.
Thanks in advance,
Chris
LikeLike
Hi Chris,
yes, provisional responses are updating future Route setting too. UE usually doesn’t get these headers, as it is sitting behind SBC (P-CSCF), which acts as B2BUA. The best place the verify the Route/record-Route headers in your IMS is to check 3GPP 24.229. (Sorry for the brief answer, I’m traveling now).
Karel.
LikeLike
Thanks, the answer is totally clear, I just asked because in the picture above it was like the UE was directly receiving the “Record-Route” list.
BR,
Chris
LikeLike
yes, that was meant in a bit more general way. In IMS SBC is the SIP client.
Cheers,
Karel.
LikeLike