UDP is still most common transport used for VoIP (hopefully that will change soon -- for proper security and privacy, TLS must be used), but by its nature of unreliable transport layer, applications must retransmit SIP packets over UDP if the next hop is not sending a response in very short time (typically, the first retransmission is done after 500ms, if no response was received). On mobile networks or congested paths, retransmissions happen quite often. The ability to detect quickly and handle them efficiently can improve the performances on SIP server side.
With the old versions, the retransmission of a request was handled by tm module, creating the transaction, then same requests were matching the transaction and processed appropriately. As early the transaction was created during the config file execution, as quick the retransmission was detected.
But a transaction is quite big structure (has space to store incoming request, its outgoing branches as well as relevant responses), creates timer tasks and uses shared memory, the last two require synchronised access, thus having impact on performances. Also, in many cases, requests are replied locally (e.g., destination user is not online, the request has to be authenticated), but the decision to reply can take a bit (e.g., a database query has to be performed for authentication).
Creating the transaction and destroying it quickly, because the request was not forwarded, doesn't sound the most optimal approach. Processing a retransmitted request till it is about to relay it stateful and see at that moment it is a retransmission, it is also affecting performances (e.g., extra database queries are done).
Kamailio 4.2 introduces a lightweight layer, which can be used between receiving a request and creating the transaction, for detecting and handling retransmissions.
TMX module can keep track of requests processed at a moment by all SIP worker processes. Instead of a full transaction structure in memory for each request, it uses a very small structure per worker process in memory, keeping only the attributes needed to match the retransmission -- again, it is not a structure per SIP request, but per SIP worker process, given that at the end of configuration file execution, the worker will create the transaction if the request is relayed.
To benefit of this feature, you have to use
t_precheck_trans() function. Default kamailio.cfg for v4.2 includes it -- the handling of retransmission is done by:
# handle retransmissions
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
The logic behind the above config snippet:
- if the request is handled by another process (t_precheck_trans() returns true), then use t_check_trans() to send the appropriate reply in the eventuality the transaction was created by that process and exit
- if the request is not handled by the another process (t_precheck_trans() returns false), then use t_check_trans() because the transaction might have been created before
Within a configuration file that creates other large structures for calls, such as dialog, this feature becomes even more useful.
Enjoy it!