The post has been edited after publishing with updated content and Kamailio modules.
Kamailio® (successor of former OpenSER and SER) is an Open Source SIP Server released under GPLv2+, able to handle thousands of call setups per second. Kamailio can be used to build large platforms for VoIP and realtime communications – presence, WebRTC, Instant messaging and other applications. Moreover, it can be easily used for scaling up SIP-to-PSTN gateways, PBX systems or media servers like Asterisk™, FreeSWITCH™ or SEMS.
kamailio.org
Introduction to Kamailio and its role in telephony is covered here. This article just describes the structure of the Kamailio source code, core and its associated modules which define the behaviour of the machine.
Kamailio architecture
Kamailio follows RFC 3261 for SIP and can act as Registrar, Location server, Proxy, Redirect or event Application Server based on its configuration. The modular architecture of Kamailio enables extending the core functionality in various directions using modules.

Kamailio Core
At the Core, Kamailio is build for SIP meesage handling. The core includes:
- memory manager
- SIP message parser
- locking system
- DNS and transport layer management (UDP, TCP, TLS, SCTP)
- configuration file parser and interpreter
- stateless forwarding
- pseudo-variables and transformations engines
- RPC control interface API
- timer API
The internal libraries include:
- components from old Kamailio cores
- database abstraction layers (DB API v1 and v2)
- management interface (MI) API
- statistics engine
Kamailio Modules
There are over 150 modules in Kamailio dealing with add-on features that can be categorised into various functional areas such as
- registrar and user location management
- accounting, authorization and authentication
- text and regular expression operations
- stateless replying
- stateful processing – SIP transaction management
Stateful | Stateless |
stateful processing is per SIP transaction Each SIP transaction will be kept in memory so that any replies, failures, or retransmissions can be recognized | Forwarding each msg in the dialog without any context. |
Application understands the transactions , for example – recognize if a new INVITE message is a resend – know that 200 OK reponse belongs to the initial INVITE which it will be able to handle in an onreply_route[x] block. | it doesnt know that the call is on-going. However it can use callId to match INVITE and BYE. |
Uses : manage call state , routing , call control like forward on busy, voicemail | Uses : Load distribution , proxying |
- SIP dialogs tracking – active calls management
- instant messaging and presence extensions
- RADIUS and LDAP support
- SQL and no-SQL database connectors
- MI and RPC transports
- Enum, GeoIP API and CPL interpreter
- topology hiding and NAT traversal
- load balancing and least cost routing
- asynchronous SIP request processing
- interactive configuration file debugger
- Lua, Perl, Python and Java SIP Servlet extensions
Routing a Call
A SIP server can either
- direct the call and let the UA contact with each other directly or
- force itself in the path by inserting a Route header in the SIP message (e record_route())
Locking Management
Kamailio provides a custom locking system its root element is a mutex semaphore, that can be set (locked) or unset (unlocked). The locking.h lib provides the functionality in C code.
Simple Locks API | Lock Set API |
gen_lock_t lock_alloc(…) lock_dealloc(…) lock_init(…) lock_destroy(…) lock_get(…) lock_try(…) lock_release(…) | gen_lock_set_t lock_set_alloc(…) lock_set_dealloc(…) lock_set_init(…) lock_set_destroy(…) lock_set_get(…) lock_set_release(…) |
A problem however with locks is that processes can eat a lot of CPU. Locking issues also occur when locks are set but not unset resulting in no more SIP messages being processed. Hence Kamailio uses gdb with PID and get backtraces to the lock that wasnt released .
gdb /path/to/kamailio PID
gdb> bt
Memory Manager
Multliple processes run simultenously within kamailio server, hence it bears private and shared memeories to facailitate their working. One can increase shared memory using -m and private memory using -M command line option.
Private Memory | Shared Memory |
Memeory is specific per process. No synchronization is needed to access structures allocated in it, such as varaibles not needed by other process or ones for temporary operations. Private memory manager is accessed via mem/mem.h | The data stored in shared memeory is visible in all Kamailio modules such as, user location, TM structures for stateful processing, routing rules for the dispatcher etc. Here locks are used to prvent race conditions. Shared memeory can be acceses via mem/shm_mem.h. |
pkg_malloc(…) pkg_free(…) pkg_realloc(…) | shm_malloc(…) shm_free(…) shm_realloc(…) |
Problems in memory management can occur due to :
- (-) Out of memory by allocating memory at runtime and not freeing it afterwards , called memory leaks
- (-) writing more than allocated for that structure, called segmentation fault.
Data Structures
str
struct sip_uri
struct sip_msg
struct msg_start
struct hdr_field
struct to_body
struct via_body
SIP Parser
kamailio has an incremental parser. Lib file for SIP message parsing is parser/msg_parser.c with the corresponding header file parser/msg_parser.h.
parse_uri(…)
parse_msg(…)
parse_headers(…)
parse_to(…)
Since kamailio has a modular architecture with core components and modules to extend the functionality, this article will be discussing few of the essential modules in Kamailio. Specific modules Discussed in this Article :
- UserLoc
- Registrar
- Dialog
- UAC
- XHTTP
- Websocket
Few categories of modules discoverable via apt-cache search kamailio
- kamailio – very fast and configurable SIP proxy
- kamailio-autheph-modules – authentication using ephemeral credentials module for Kamailio
- kamailio-berkeley-bin – Berkeley database module for Kamailio – helper program
- kamailio-berkeley-modules – Berkeley database module for Kamailio
- kamailio-carrierroute-modules – carrierroute module for Kamailio
- kamailio-cnxcc-modules – cnxcc modules for Kamailio
- kamailio-cpl-modules – CPL module (CPL interpreter engine) for Kamailio
- kamailio-dbg – very fast and configurable SIP proxy [debug symbols]
- kamailio-dnssec-modules – contains the dnssec module
- kamailio-erlang-modules – earlang modules for Kamailio
- kamailio-extra-modules – extra modules for Kamailio
- kamailio-geoip-modules – contains the geoip module
- kamailio-ims-modules – IMS module for Kamailio
- kamailio-java-modules – contains the app_java module
- kamailio-json-modules – Json parser and jsonrpc modules for Kamailio
- kamailio-kazoo-modules – kazoo modules for Kamailio
- kamailio-ldap-modules – LDAP modules for Kamailio
- kamailio-lua-modules – contains the app_lua module
- kamailio-memcached-modules – interface to memcached server
- kamailio-mono-modules – contains the app_mono module
- kamailio-mysql-modules – MySQL database connectivity module for Kamailio
- kamailio-outbound-modules – Outbound module for Kamailio
- kamailio-perl-modules – Perl extensions and database driver for Kamailio
- kamailio-postgres-modules – PostgreSQL database connectivity module for Kamailio
- kamailio-presence-modules – SIMPLE presence modules for Kamailio
- kamailio-purple-modules – Provides the purple module, a multi-protocol IM gateway
- kamailio-python-modules – contains the app_python module
- kamailio-radius-modules – RADIUS modules for Kamailio
- kamailio-redis-modules – Redis database connectivity module for Kamailio
- kamailio-sctp-modules – sctp module for Kamailio
- kamailio-snmpstats-modules – SNMP AgentX subagent module for Kamailio
- kamailio-sqlite-modules – SQLite database connectivity module for Kamailio
- kamailio-tls-modules – contains the TLS kamailio transport module
- kamailio-unixodbc-modules – unixODBC database connectivity module for Kamailio
- kamailio-utils-modules – Provides a set utility functions for Kamailio
- kamailio-websocket-modules – Websocket module for kamailio
- kamailio-xml-modules – XML based extensions for Kamailio’s Management Interface
- kamailio-xmpp-modules – XMPP gateway module for Kamailio
The first set under explanation is Usrloc and Register module which take care of user persistance in Database and handling an incoming register request with authentication and validation.
The first set under explanation is Usrloc and Register module which take care of user persistance in Database and handling an incoming register request with authentication and validation.
Usrloc Module
Keeps a user location table and provides access to the table for other modules.
Parameters:
- nat_bflag
- user_column
- domain_column
- contact_column
- expires_column
- q_column
- callid_column
- cseq_column
- methods_column
- flags_column
- cflags_column
- user_agent_column
- received_column
- socket_column
- path_column
- ruid_column
- instance_column
- server_id_column
- connection_id_column
- keepalive_column
- partition_column
- use_domain
- desc_time_order
- timer_interval
- db_url
- db_mode
- db_load
- db_insert_update
- matching_mode
- cseq_delay
- fetch_rows
- hash_size
- preload
- db_update_as_insert
- db_check_update
- timer_procs
- xavp_contact
- db_ops_ruid (int)
- handle_lost_tcp (int)
- close_expired_tcp (int)
- expires_type (int)
- db_raw_fetch_type (int)
- db_insert_null (int)
- skip_remote_socket (int)
- db_timer_clean (int)
- server_id_filter (int)
RPC Commands
ul.dump
ul.lookup table AOR
ul.rm table AOR
ul.rm_contact table AOR contact
ul.flush
ul.add
ul.db_users
ul.db_contacts
ul.db_expired_contacts
Statistics
users
contacts
expires
registered_users
Functions
- ul_register_domain(name)
- ul_insert_urecord(domain, aor, rec)
- ul_delete_urecord(domain, aor)
- ul_delete_urecord_by_ruid(domain, ruid)
- ul_get_urecord(domain, aor)
- ul_lock_udomain(domain)
- ul_unlock_udomain(domain)
- ul_release_urecord(record)
- ul_insert_ucontact(record, contact, expires, q, callid, cseq, flags, cont, ua, sock)
- ul_delete_ucontact (record, contact)
- ul_get_ucontact(record, contact)
- ul_get_all_ucontacts (buf, len, flags)
- ul_update_ucontact(contact, expires, q, callid, cseq, set, res, ua, sock)
- ul_bind_ursloc( api )
- ul_register_ulcb(type ,callback, param)
- ul_get_num_users()
Registrar Module
SIP registration processing logic can be defined here.
Path support – off , lazy , strict ( RFC 3327)
GRU ( Globally Routbale User agent URIs) support – public , temporary ( RFC 5627)
Dependencies :
- usrloc – User Location Module.
- sl – Stateless Replies.
Parameters :
- default_expires
- default_expires_range
- expires_range
- min_expires
- max_expires
- default_q
- realm_prefix
- append_branches
- aor_avp (str)
- case_sensitive
- received_avp (str)
- received_param
- max_contacts
- retry_after
- sock_flag
- sock_hdr_name
- method_filtering
- use_path
- path_mode
- path_use_received
- path_check_local
- reg_callid_avp
- xavp_cfg
- xavp_rcd
- gruu_enabled
- outbound_mode
- regid_mode
- flow_timer
- contact_max_size
Functions :
- save(domain, [, flags [, uri]])
- lookup(domain [, uri])
- lookup_branches(domain)
- registered(domain [, uri [, match_option [, match_action]]])
- add_sock_hdr(hdr_name)
- unregister(domain, uri[, ruid])
- reg_fetch_contacts(domain, uri, profile)
- reg_free_contacts(profile)
Event Routes :
event_route[usrloc:contact-expired]
Statistics :
max_expires
max_contacts
default_expires
accepted_regs
rejected_regs
Dialog Module
We know that dialog represent the p2p relationship between 2 sip clients and contains sequence of transactions along with routing information and facilitate sequencing of more messages. Dialog module keeps track of current dialogs also provides API support. It can be loaded and used as
loadmodule "dialog.so"
..
# ---- dialog params ----
modparam("dialog", "enable_stats", 1)
modparam("dialog", "dlg_flag", 4)
modparam("dialog", "event_callback", "ksr_dialog_event")
Parameters :
- enable_stats
- hash_size
- rr_param
- dlg_flag
- timeout_avp
- default_timeout
- early_timeout
- noack_timeout
- end_timeout
- dlg_extra_hdrs
- dlg_match_mode
- detect_spirals
- db_url
- db_mode
- db_update_period
- db_fetch_rows
- db_skip_load
- table_name
- call_id_column
- from_uri_column
- from_tag_column (string)
- to_uri_column (string)
- to_tag_column (string)
- from_cseq_column (string)
- to_cseq_column (string)
- from_route_column (string)
- to_route_column (string)
- from_contact_column (string)
- to_contact_column (string)
- from_sock_column (string)
- to_sock_column (string)
- h_id_column (string)
- h_entry_column (string)
- state_column (string)
- start_time_column (string)
- timeout_column (string)
- sflags_column (string)
- toroute_name_column (string)
- vars_table_name
- vars_h_id_column
- vars_h_entry_column
- vars_key_column
- vars_value_column (string)
- profiles_with_value (string)
- profiles_no_value (string)
- bridge_controller (string)
- bridge_contact (string)
- initial_cbs_inscript (int)
- send_bye (int)
- wait_ack (int)
- ka_timer (int)
- ka_interval (int)
- ka_failed_limit (int)
- timeout_noreset (int)
- timer_procs (int)
- enable_dmq (int)
- track_cseq_updates (int)
- lreq_callee_headers (string)
- event_callback (str) – name of the function in the kemi configuration file (embedded scripting language such as Lua, Python, …) to be executed instead of event_route[…] blocks.
The callback function receives a string parameter with the name of the event, the values are: ‘dialog:start’, ‘dialog:end’, ‘dialog:failed’. It is also executed if ‘$dlg_ctx(timeout_route)’ is set
function ksr_dialog_event(evname) KSR.info("===== dialog module triggered event: " .. evname .. "\n"); if (evname == "dialog:end") or (evname == "dialog:failed") then logger.log("info", "in dialog event callback with event-name - " .. evname .. " start CDR process ") if not cdrProcess.post() then logger.log("err", "Failed") else logger.log("info", "successfully posted") core.exit() end end end
- h_id_start (int)
- h_id_step (int)
Functions :
- set_dlg_profile(profile,[value])
- unset_dlg_profile(profile,[value])
- is_in_profile(profile,[value])
- get_profile_size(profile,[value],size)
- dlg_isflagset(flag)
- dlg_setflag(flag)
- dlg_resetflag(flag)
- dlg_bye(side)
- dlg_refer(side, address)
- dlg_manage()
- dlg_bridge(from, to, op)
- dlg_get(callid, ftag, ttag)
- is_known_dlg()
- dlg_set_timeout(timeout [, h_entry, h_id])
- dlg_set_timeout_by_profile(profile, [value], timeout)
- dlg_set_property(attr)
- dlg_remote_profile(cmd, profile, value, uid, expires)
- dlg_set_ruri()
Statistics :
active_dialogs
early_dialogs
processed_dialogs
expired_dialogs
failed_dialogs
RPC Commands :
dlg.list
dlg.list_ctx
dlg.dlg_list
dlg.dlg_list_ctx
dlg.terminate_dlg
dlg.end_dlg
dlg.profile_get_size
dlg.profile_list
dlg.bridge_dlg
Exported Variables :
$DLG_count
$DLG_status
$DLG_lifetime
$dlg(…)
$dlg_ctx(…)
$dlg_var(key)
Event Routes :
event_route[dialog:start] , event_route[dialog:end] , event_route[dialog:failed]
UAC module
This set deals with RTP proxy and RTP engine which are used for proxing media streams via kamailio server.
This set deals with HTTP and Websocket adapters to handle web based ( such as webRTC) calls on kamailio.
XHTTP
Provides basic HTTP/1.0 server functionality. SIP requires a Content-Length header for TCP transport. But most HTTP clients do not set the content length for normal GET requests. Therefore, the core must be configured to allow incoming requests without content length header:
tcp_accept_no_cl=yes
Parameters :
- url_skip : if there is a match , event route is not executed
modparam(“xhttp”, “url_skip”, “^/RPC2”)
- url_match : if there is no match , event route is not executed
modparam(“xhttp”, “url_match”, “^/sip/”)
- event_Callback : function in the kemi configuration file (embedded scripting language such as Lua, Python) to be executed instead of event_route[xhttp:request] block
modparam("xhttp", "event_callback", "ksr_xhttp_event") // and the event callback function implemented in Lua function ksr_xhttp_event(evname) KSR.info("===== xhttp module triggered event: " .. evname .. "\n"); return 1; end
Function
- xhttp_reply(code, reason, ctype, body) – Send back a reply with content-type and body.
event_route[xhttp:request] { xhttp_reply("200", "OK", "" , ""); xhttp_reply("403", "Forbidden", "", ""); }
Event Routes
xhttp:request
The event route is executed when a new HTTP request is received.
event_route[xhttp:request] { xhttp_reply("200", "OK", "text/html", "<html><body>OK</body></html>"); }
Websocket Module
This module provides websocket ( ws and wss) support to kamailio ( RFC 6455). Handles handshaking, management (including connection keep-alive), and framing for the SIP and MSRP WebSocket sub-protocols (RFC 7118 and RFC 7977).
References :
[1] SER Getting started : https://kamailio.org/docs/ser-getting-started/SER-GettingStarted.pdf
[2] Registrar module in kamailio http://kamailio.org/docs/modules/stable/modules/registrar.html