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.
nice! Daring to add one alternative - rpc set instead of reload (htable defined with dbmode=1): kamctl rpc htable.sets config maint s:1
— miconda (@miconda) March 12, 2021
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 😎