Kamailio
Overview
SIP server Kamailio(former OpenSER) 내용 정리.
Basic
Kamailio 는 SIP 에 특화된 오픈 소스 라우터/방화벽 이다.
Installation
Startup script
/etc/systemd/kamailio.service
[Unit] Description=Kamailio SIP Server Documentation=man:kamailio(8) http://www.kamailio.org/ After=syslog.target network-online.target [Service] Type=forking User=kamailio Environment=SHM_SIZE=64 Environment=PKG_SIZE=8 ExecStartPre=/usr/sbin/kamailio -c ExecStart=/usr/sbin/kamailio -m $SHM_SIZE -M $PKG_SIZE \ -P /run/kamailio/kamailio.pid ExecStopPost=/usr/bin/rm -f /run/kamailio/kamailio.pid PIDFile=/run/kamailio/kamailio.pid Restart=on-failure RestartSec=30 [Install] WantedBy=multi-user.target
/etc/tmpfiles.d/kamailio.conf
d /run/kamailio 0750 kamailio kamailio
Structure
Kamailio 의 configuration file 은 크게 다음의 파트로 이루어져 있다.
- global parameters
- modules settings
- routing blocks
Global parameters section
This is the first part of the configuration file, containing the parameters for the core of kamailio and custom global parameters.
Typically this is formed by directives of the form:
name=value
The name corresponds to a core parameters. If a name is not matching a core parameter, then Kamailio will not start, rising an error during startup.
Modules setting section
This is the second section of the configuration file, containing the directives to load modules and set their parameters.
It contains the directives loadmodule and modparam. In the default configuration file starts with the line setting the path to modules(the assignment to mpath core parameter).
loadmodule "debugger.so" ... modparam("debugger", "cfgtrace", 1)
Routing blocks section
This is the last section of the configuration file, typically the biggest one, containing the routing blocks with the routing logic for SIP traffic handled by Kamailio. The only mandatory routing block is request_route, which contains the actions for deciding the routing for SIP requests.
request_route { # per request initial checks route(REQINIT); ... } branch_route[MANAGE_BRANCH] { xdbg("new branch [$T_branch_idx] to $ru\n"); route(NATMANAGE); }
Generic elements
Comments
Line comments start with # or //. Block comments start with /* and are ended by */.
# this is a line comment // this is another line comment /* this is a block comment */
Values
There are three types of values.
- integer : number of 32bit size.
- boolean: aliases to 1 (true, on, yes) or 0(false, off, no).
- string: tokens enclosed in between double or single quotes.
// next two are strings "this is a string value" 'this is another string value" // next is a boolean yes // next is an integer 64
Identifiers
Identifiers are tokens which are not enclosed in single or double quotes and to match the rules for integer or boolean values. For example, the identifiers are the core parameters and functions, module functions, core keywords and statements.
return
Variables
The variables start with $.
$var(x) = $rU + "@" + $fd;
Actions
An action is an element used inside routing blocks ended by ;. It can be an execution of a function from core or a module, a conditional or loop statement, an assignment expression.
sl_send_reply("404", "Not found"); exit;
Expressions
An expression is an association group of statements, variables, functions and operators.
if(!t_relay()) if($var(x)>10) "sip:" + $var(prefix) + $rU + "@" + $rd
Config pre-processor directives
Include_file
include_file "path_to_file"
Include the content of the file in config before parsing. path_to_file must be a static string. Including file operation is done at startup. If you change the content of included file, you have to restart the SIP server to become effective.
The path_to_file can be relative or absolute. If it is not absolute path, first attempt is to locate it relative to current directory, and if fails, relative to directory of the file that includes it. There is no restriction where include can be used or what can contain - any part of config file is ok. There is a limit of maximum 10 includes in depth, otherwise you can use as many includes as you want. Reporting of the cfg file syntax errors prints now the file name for easier trouble shooting.
If the included file is not found, the config file parser throws error. You can find this error message at the logging destination, usually in the system logging(file).
You can use also the syntax #!include_file or !!include_file.
route { ... include_file "/sr/checks.cfg" ... } --- /sr/checks.cfg --- if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; } ---
import_file
import_file "path_to_file"
Similar to include_file, but does not throw error if the included file is not found.
define
Control in C-style what parts of the config file are executed. The parts in non-defined zones are not loaded, ensuring lower memory usage and faster execution.
Available directives:
- #!define NAME : define a keyword.
- #!define NAME VALUE : define a keyword with value.
- #!ifdef NAME : check if a keyword is defined.
- #!else : switch to false branch of ifdef/ifndef region.
- #!endif : end ifdef/ifndef region.
- #!trydef : add a define if not already defined.
- #!redefine : force redefinition even if already defined.
Among benefits:
- easy way to enable/disable features (e.g. see default cfg - controlling support of nat traversal, presence, etc...)
- switch control for parts where conditional statements were not possible (e.g. global parameters, module settings).
- faster by not using conditional statements inside routing blocks when switching between running environments.
... #!define TESTBED_MODE #!ifdef TESTBED_MODE debug=5 log_stderror=yes listen=192.168.1.1 #!else debug=2 log_stderror=no listen=10.0.0.1 #!endif ... #!ifdef TESTBED_MODE modparam("acc|auth_db|usrloc", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio_testbed") #!else modparam("acc|auth_db|usrloc", "db_url", "mysql://kamailio:kamailiorw@10.0.0.2/kamailio_production") #!endif ... #!ifdef TESTBED_MODE route[DEBUG] { xlog("SCRIPT: SIP $rm from: $fu to: $ru - srcip: $si"\n); } #!endif ... route { #!ifdef TESTBED_MODE route(DEBUG); #!endif ... } ...
You can define values for IDs
#!define MYINT 123 #!define MYSTR "xyz"
Defined IDs are replaced at startup, during config parsing.
$var(x) = 100 + MYINT
You can have multi-line defined IDs
#!define IDLOOP $var(i) = 0; \ while($var(i)<5) { \ xlog("++++ $var(i)\n"); \ $var(i) = $var(i) + 1; \ }
Note
- Number of allowed defines is now set to 256.
- Multilines defines are reduced to single line, so line counter should be fine.
- Column counter goes inside the define value, but you have to omit the '\' and CR for the accurate inside-define position.
- Text on the same line as the directive will cause problems. Keep the directive lines clean and only comment on a line before or after.
subst
Perform substitutions inside the strings of config (note that define is replacing only IDs : alphanumeric tokens not enclosed in quotes.
- #!subst offers an easy way to search and replace inside strings before cfg parsing.
- flags is optional and can be 'i' - ignore case, 'g' - global replacement.
#!subst "/regexp/subst/flags"
This will do the substitution of db password in db_url parameter value.
#!subst "/DBPASSWD/xyz/" modparam("acc", "db_url", "mysql://user:DBPASSWD@localhost/db")
substdef
#!substdef "/ID/subst/"
Similar to subst, but in addition it adds a #!define ID subst.
See also
- https://www.kamailio.org - kamailio 공식 홈페이지