March 12, 2021

483 words 3 mins read

Kamailio : Server Maintenance Mode

Kamailio : Server Maintenance Mode

Sometimes your Kamailio server might need server maintenance and for that you could require a way to drain out traffic. Also, depending on where it sits in your design you might want to return a custom response code so that new traffic routes elsewhere.

There is a simple trick to doing this. The idea is simple, set a variable and check its status/value and based on that decide on how to handle new requests.

To keep the setting persistent across reboots, we will store it in a database, but for fast processing, we will load it into memory and keep it in Kamailio’s hash table. For this we would need to enable the htable module.

Database

Lets quickly create a table in the Kamailio backend database. This example is for a MySQL database:

CREATE TABLE `htable_config` (
  `id` int(11) NOT NULL,
  `key_name` varchar(64) NOT NULL DEFAULT '',
  `key_type` int(11) NOT NULL DEFAULT '0',
  `value_type` int(11) NOT NULL DEFAULT '0',
  `key_value` varchar(128) NOT NULL DEFAULT '',
  `expires` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

Lets insert a variable called ‘maint’ with a value (key_value) of ‘0’. The resulting table looks like:

+----+----------+----------+------------+-----------+---------+
| id | key_name | key_type | value_type | key_value | expires |
+----+----------+----------+------------+-----------+---------+
|  1 | maint    |        0 |          0 | 0         |       0 |
+----+----------+----------+------------+-----------+---------+
Config file

In the configuration file, first we add the parameters for the htable module. We will call our in memory hash table config

# ----- htable params -----
modparam("htable","db_url",DBURL)
modparam("htable","htable", "config=>size=3;dbtable=htable_config;")

With the variable and value loaded at startup we can now make ‘status’ checks in the routing logic

if (is_method("INVITE") && !has_totag()) {
       #
       # Is there ongoing maintenance?
       if ($sht(config=>maint)=="1") {
           xlog ("L_INFO","Ongoing maintenance. Call-ID:$ci | Method: $rm");
           sl_send_reply("503", "Maintenance");
           exit;
       }
}       

The reply sent back can be whatever suits your environment.

Enabling/disabling

With this configuration in place, triggering maintenance would be done in 2 steps. First we update the database table and set our variable 'maint' to ‘1’:

UPDATE TABLE htable_config SET key_value='1' WHERE key_name='maint';

Then on the Kamailio server we just reload the in memory hash table:

kamcmd htable.reload config

And that’s it, we are in maintenance mode!

UPDATE

I got a twitter comment showing a nice use of RPC as an alternative method of setting or unsetting the maintenace variable. This is the beauty of the felxibiltiy of Kamailio, there are multiple ways of doing things.

Conclusion

In this example, when we activate maintenance mode, new INVITES will receive a 503 response but existing calls will still be processed. The return code can be any that suits your environment and, of course, this logic can be applied to any request of your choice.

Keep flying Kamailio 😎