Wednesday, October 22, 2014

Kamailio 4.2 Tips: #9 - Asynchronous Route Execution - DNS

I got dragged back in the asynchronous loop by several folks here at AstriCon, so again another tip for it.

Kamailio had a lot of asynchronous processing options for many years (including the transport layer TCP /TLS). Kamailio 4.2 brought in more options or simplified some of the existing alternatives. See also some of the previous posts in this series.

The subject of this post is asynchronous config route block execution. Technically it is about delegating immediate execution of a group of actions from configuration file to another process than the SIP worker and can be used for various needs, not tied to something specific. For that reason, the example is about doing sort of asynchronous DNS handling (dedicated to Torrey, developer of sipt module, following the discussion after AstriDevCon day, at this moment busy with the hackatron).

There is a lot of SIP traffic that doesn't require DNS -- for example: traffic terminated on the server, like REGISTER, presence requests, requests within dialog, calls between users registered locally (location service). Likely to have an hostname as next hop address are: requests sent to foreign SIP providers or calls sent to PSTN termination providers. Depending on the type of the service, there can be more or less percentage of SIP requests that need to do DNS lookup. However, DNS query can take a while, so it is an obvious benefit of avoiding such operation in a SIP worker.

How to do it: first, the number for asynchronous workers has to be set via global parameter: async_workers. Then, the async module provides a new config function: async_task_route("rname").

The missing piece would be how to decide whether forwarding of the message involves DNS or not. That is simple to do with:
  • $nh(d) - variable returning the next hop domain
  • is_ip(...) - function exported by ipops module which can detect if an address is IP or not
Next are the relevant config snippets:

request_route {
...
    if(!is_ip("$nh(d)")) {
        if(!async_task_route("DNSRELAY")) {
            send_reply("500", "Server error");
        }
        exit;
    }
...
}

route[DNSRELAY] {
    if (!t_relay()) {
        t_reply("500", "Server error");
    }
    exit;
}


Enjoy it!


No comments:

Post a Comment