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 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.
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())
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.
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 .
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.
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.
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
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
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.
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).
We know the power of the Internet protocol suite as it takes on the world of telecom. Already half of the Communication has been transferred from legacy telecom signalling protocols like SS7 to IP based communication ( Skype, Hangouts, WhatsApp, Facebook Messenger, Slack, Microsoft Teams ). The TV service providers too are largely investing in IP based systems like SIP and IMS to deliver their content over Telecom’s IP based network ( Packet-switched ).
IPTV
A consumer today wants HD media content anytime anywhere. The traditional TV solutions just dont match upto the expectations anymore. The IPTV provider in todays time must make investments to deliver content that is media-aware, and device-aware. Not only this it should be personal, social, and interactive and enhance the user experience.
Few popular applications for IPTV solutions developers :
Menu overlay with detailed description of channels , categories , programs , movies
Record and Replay option also referred to as timeshift. It allows a user to pause , resume and record the show in his absence and view it later
Video on demand which concerns paying and viewing music albums , movies etc on demand
Live streaming of events such as president speech , tennis match etc .
Application that can be build around the IPTV context
Record and Playback content
Information overlay on streaming content
Social networking services integrated with IPTV content
Parental Control to realtime view , monitor and control what your child is watching on the IPTV
Watch the surveillance footage from IP cameras anywhere
Real time communication on IPTV with advanced features like call continuity , content sync .
Mobile TV is an advanced services that lets users download and play songs and videos, send text messages, conference with colleagues and friends, and exchange pictures or videos on whichever device they are using.
Mobile TV Service platform bundles different types of content (live TV, VoD, podcast, etc.) into IP service streams and selects the transmission bearer depending on the targeted audience.
broadcast (DVB-H or DVB-SH based)
unicast (2G, 3G, etc.)
DVB-H standard is optimized transmission on brodcast technology for hand-held, low power devices.
Components
bearer selection
Electronic Service Guide (ESG) to list the available programs and contents.
Streaming servers
Video Encoders
rich media service node
Adons
recommendation engine
personalized advertising
audience measurement
Content and subscriber management
(+) use existing cellular networks
radio sites and antennas enhanced with broadcast repeaters
Video on demand using Adaptive Multirate dispatch using AWS Transcoder
Componets
HTML5 webpage on chrome browser for WebRTC input : contains the client side script to record the video and send the blob to server side for processing.
Amazon EC2 instance : The amazon ec2 instance hosts the web interface for login and video recording . It converts the incoming blob / webm format to mp4 . After the video conversion it uploads the video mp4 to s3 bucket.
Amazon S3 bucket : The s3 bucket is connected to the transcoder via pipeline and holds the video storage as well.
Amazon transcoder : The transcoder provides adaptive multirate dispatch on viewer access .
RDS for any mysql storage ( optional ) : Optional for record keeping credentials, storage links, linked information etc.
WebRTC has been applied in the basic communication sector with overwhelming results. However there the capability to stream media is not just limited to communication it can be applied to stream multimedia content from streaming servers as well. This section describes the application of WebRTC in IPTV ( IP Television ), VOD ( Video on Demand ), Online FM ( audio from Radio stations online ) applications. All this without the need to download plugins or any additional installations of third party products. Also with the inclusion of the
An architecture representing some of these use cases in the context of WebRTc based media transmission is depicted below.
Kamailio™ (former OpenSER) is an Open Source SIP Server released under GPL.
Kamailio primarily acts as a SIP server for VOIP and telecommunications platforms under various roles and can handle load of hight CPS ( Calls per second ) with custom call routing logic with the help of scripts.
Rich features set suiting to telephony domain that includes IMS extensions for VoLTE; ENUM; DID and least cost routing; load balancing; routing fail-over; Json and XMLRPC control interface, SNMP monitoring.
To integrate with a carrier grade telecom network as SBC / gateway / inbound/outbound proxy , it can act as IPv4-IPv6 gateway , UDP/TCP/SCTP/WS translator and even had NAT and anti DOS attack support .
If Kamailio is the central to the VoIP system it can also perform accounting with rich database extensions Mysql PostgreSQL UnixODBC Berkeley DB Oracle Redis, MongoDB Cassandra etc
Kamailio is SIP (RFC3261) compliant
It can work as Registrar or Location server. For SIP call logic it can become a Proxy or SIP Application server. Can also act like a Redirect, Dispatcher or simply a SIP over websocket server.
Customisable and Felxible
It can be embedded to devices as the binary file is small size. Additional modules can be appended for more functions with the same core.
Modular architecture – core, internal libraries , module interface and ability to extend functionality with scripts such as LUA, Kamailio can be readily integrated to a VOIP ecosystem.
Also NAT traversal support for SIP and RTP traffic ( suited to be WebRTC server ) . Read more about kamailio DNS subsystem management , load balancing , NAT and NAThelper modules in Kamailio DNS and NAT.
Among other features it offers load balancing with many distribution algorithms and failover support, flexible least cost routing , routing failover and replication for High Availability (HA).
Can be readily integrated with external databases, caches, notification system ( SNS , APNS , GCM ), VoIP monitors, CDR processors, API systems etc for efficient call processing.
Transport Layers supported
UDP, TCP, TLS and SCTP
IPv4 and IPv6
gateways via (IPv4 to IPv6, UDP to TLS, a.s.o.)
SCTP multi-homing and multi-streaming
WebSocket for WebRTC
Asynchronous TCP, UDP and SCTP
Asynchronous SIP message processing and inter-process message queues communication system
Secure Communication ( TLS + AAA)
Digest SIP User authentication
Authorization via ACL or group membership
IP and Network authentication
TLS support for SIP signaling
transparent handling of SRTP for secure audio
TLS domain name extension support
authentication and authorization against database (MySQL, PostgreSQL, UnixODBC, BerkeleyDB, Oracle, text files), RADIUS and DIAMETER
Kamailio Security here for snaity, ACL permission , firewall , flood detection , topology hiding and digests.
topology hiding – hide IP addresses in SIP headers to protect your network architecture
Accounting
Kamailio gives event based and configurable accounting data details. Can show multi-leg call accounting ( A leg to B leg ). It can store to database, Radius or Diameter based on module used . Has a prepaid engine.
External Interaction
text-based management interface via FIFO file, udp, xmlrpc and unix sockets.
RPC control interface – via XMLRPC, UDP or TCP
Rich Communication Services (RCS)
SIP SIMPLE Presence Server (rich presence)
Presence User Agent ( SUBSCRIBE , NOTIFY and PUBLSH)
XCAP client capabilities and Embedded XCAP Server
Presence DialogInfo support – SLA/BLA
Instant Messaging ( IM)
Embedded MSRP relay
Monitoring and Troubleshooting
Support for SNMP – interface to Simple Network Management Protocol. For Debugging it has config debugger , remote control via XMLRPC and error message logging system .Provides internal statistics exported via RPC and SNMP.
Extensibility APIs
The supported one are Perl , Java SIP Servlet Application Interface , Lua , Managed Code (C#) , Python.
(MySQL, PostgreSQL, SQLite, UnixODBC, BerkeleyDB, Oracle, text files) and other database types which have unixodbc drivers. ‘
It can have connections pool and different backends be used at same time (e.g., accounting to Oracle and authorization against MySQL).
Has connectors for Memcached, Redis , MongoDB and Cassandra no-SQL backends
Interconnectivity
Acts as SIP to PSTN gateway and gateway to sms or xmpp and other IM services. Has Interoperability with SIP enabled devices and applications such as SIP phones (Snom, Cisco, etc.), Media Servers (Asterisk, FreeSwitch, etc). More details on Kamailio as Inbound/Outbound proxy or Session Border Controller (SBC) here
Read RTP engine on kamailio SIP server which focuses on setting up sipwise rtpegine to proxy rtp traffic from kamailio app server. Also daemon and kernal modules. ,transcoding , in-kernel packet forwarding , ngcontrol protocol etc.
To validate and verify the location of kamillio use ‘which kamailio’ which returns /usr/sbin/kamailio
For Modules installation, check all avaible modules with command ‘apt search kamailio’and to install a new module such as websockt module use ‘apt install kamailio-websocket-modules’
Databaseaccess : After installaing kamailio , edit the kamailio.cfg file in /etc/kamailio to set the reachabe SIP domain, database engine, username/password etc to connect to databaseand enable the kamdbctl script to run and create users and tables, etc.
SIP_DOMAIN=kamailio.org
SIP_DOMAIN=17.3.4.5
chrooted directory
$CHROOT_DIR=”/path/to/chrooted/directory”
database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE by default none is loaded
DBENGINE=MYSQL
Run kamdbctl to create users and database now
kamdbctl create
the database created is name kamailio and its tables are
The Kamailio configuration file for the control tools. Can set variables used in the kamctl and kamdbctl setup scripts. Per default all variables here are commented out, the control tools will use their internal default values. This file lets to edit SIP domain, the database engine, username/password/ to connect to database, etc.
## your SIP domain SIP_DOMAIN=1.1.1.1
## chrooted directory# $CHROOT_DIR="/path/to/chrooted/directory"## database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE# by default none is loaded
# If you want to setup a database with kamdbctl, you must at least specify this parameter.
DBENGINE=MYSQL## database host# DBHOST=localhost# DBPORT=3306## database name (for ORACLE this is TNS name)# DBNAME=kamailio# database path used by dbtext, db_berkeley or sqlite# DB_PATH="/usr/local/etc/kamailio/dbtext"
database read/write user# DBRWUSER="kamailio"## password for database read/write user# DBRWPW="kamailiorw"
database read only user
# DBROUSER="kamailioro"## password for database read only user# DBROPW="kamailioro"## database access host (from where is kamctl used)# DBACCESSHOST=192.168.0.1
database super user (for ORACLE this is ‘scheme-creator’ user)
# DBROOTUSER="root"## password for database super user## - important: this is insecure, targeting the use only for automatic testing## - known to work for: mysql# DBROOTPW="dbrootpw"## database character set (used by MySQL when creating database)#CHARSET="latin1"## user name column# USERCOL="username"# SQL definitions# If you change this definitions here, then you must change them# in db/schema/entities.xml too.
# FIXME# FOREVER="2030-05-28 21:32:15"# DEFAULT_Q="1.0"# Program to calculate a message-digest fingerprint# MD5="md5sum"# awk tool# AWK="awk"# gdb tool# GDB="gdb"# If you use a system with a grep and egrep that is not 100% gnu grep compatible,# e.g. solaris, install the gnu grep (ggrep) and specify this below.grep tool# GREP="grep"# egrep tool# EGREP="egrep"# sed tool# SED="sed"# tail tool# LAST_LINE="tail -n 1"# expr tool# EXPR="expr"
Describe what additional tables to install. Valid values for the variables below are yes/no/ask. With ask (default) it will interactively ask the user for an answer, while yes/no allow for automated, unassisted installs.
#If to install tables for the modules in the EXTRA_MODULES variable.
# INSTALL_EXTRA_TABLES=ask# If to install presence related tables.# INSTALL_PRESENCE_TABLES=ask# If to install uid modules related tables.# INSTALL_DBUID_TABLES=ask
Define what module tables should be installed.
If you use the postgres database and want to change the installed tables, then you must also adjust the STANDARD_TABLES or EXTRA_TABLES variable accordingly in the kamdbctl.base script.
standard modules
# STANDARD_MODULES="
standard acc lcr domain group permissions registrar usrloc msiloalias_db uri_db speeddial avpops auth_db pdt dialog dispatcherdialplan"
extra modules
# EXTRA_MODULES="imc cpl siptrace domainpolicy carrierroute userblacklist htable purple sca"type of aliases used: DB - database aliases; UL - usrloc aliases- default: none , ALIASES_TYPE="DB"control engine: RPCFIFO
- default RPCFIFOCTLENGINE="RPCFIFO"## path to FIFO file for engine RPCFIFO# RPCFIFOPATH="/var/run/kamailio/kamailio_rpc_fifo"## check ACL names; default on (1); off (0)# VERIFY_ACL=1## ACL names-if VERIFY_ACL is set,only the ACL names from below list are accepted# ACL_GROUPS="local ld int voicemail free-pstn"## check if user exists (used by some commands such as acl);## - default on (1); off (0)# VERIFY_USER=1## verbose - debug purposes - default '0'# VERBOSE=1## do (1) or don't (0) store plaintext passwords## in the subscriber table - default '1'# STORE_PLAINTEXT_PW=0
Kamailio START Options
PID file path – default is: /var/run/kamailio/kamailio.pid
config files are used to customize and deploy SIP services since each and every SIP packet is route based on policies specified in conf file ( routing blocks ). Location when installed from source – /usr/local/etc/kamailio/kamailio.cfg , when installed from package – /etc/kamailio/kamailio.cfg
The features in config file :-
User authentication
Kamailio doesn’t have user authentication by default , so to enable it one must
#!define WITH_MYSQL
#!define WITH_AUTH
kamdbctl tool is to be used for creating and managing the database.
kamdbctl create
Kamctl is used for adding subscriber information and password.
kamctl add altanai1 123mysql: [Warning] Using a password on the command line interface can be insecure.MySQL password for user 'kamailio@localhost': mysql: [Warning] Using a password on the command line interface can be insecure.new user 'altanai1' added
More details in Tools section below .
IP authorization
accounting
registrar and location servicesTo have persisant location enabled so that records are not lost once kamailio are restarted , we need to save it to database and reload when restarting
#!define WITH_USRLOCDB
attacks detection and blocking (anti-flood protection)
NAT traversal
requires RTP proxy for RTP relay. NAT traversal support can be set by
#!define WITH_NAT
short dialing on server
multiple identities (aliases) for subscribers
multi-domain support
routing to a PSTN gateway
routing to a voicemail server
TLS encryption
instant messaging (pager mode with MESSAGE requests)
To enable IP authentication execute: enable mysql , enable authentication , define WITH_IPAUTH and add IP addresses with group id ‘1’ to ‘address’ table.
enable mysql
define WITH_MULTIDOMAIN
...
#!ifdef WITH_MULTIDOMAIN# - the value for 'use_domain' parameter
#!define MULTIDOMAIN 1
#!else
#!define MULTIDOMAIN 0
#!endif
To enable TLS support execute:
adjust CFGDIR/tls.cfg as needed
define WITH_TLS
To enable XMLRPC support :
define WITH_XMLRPC
adjust route[XMLRPC] for access policy
To enable anti-flood detection execute:
adjust pike and htable=>ipban settings as needed (default is block if more than 16 requests in 2 seconds and ban for 300 seconds)
define WITH_ANTIFLOOD
...
route[REQINIT] {
#!ifdef WITH_ANTIFLOOD
# flood detection from same IP and traffic ban
if(src_ip!=myself) {
if($sht(ipban=>$si)!=$null) {
# ip is already blocked
xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
exit;
}
if (!pike_check_req()) {
xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
$sht(ipban=>$si) = 1;
exit;
}
}
if($ua =~ "friendly-scanner") {
sl_send_reply("200", "OK");
exit;
}
#!endif
..
}
To block 3XX redirect replies execute:
define WITH_BLOCK3XX
To enable VoiceMail routing :
define WITH_VOICEMAIL
set the value of voicemail.srv_ip and adjust the value of voicemail.srv_port
ifdef WITH_VOICEMAIL
# VoiceMail Routing on offline, busy or no answer
# - by default Voicemail server IP is empty to avoid misrouting
voicemail.srv_ip = "" desc "VoiceMail IP Address"
voicemail.srv_port = "5060" desc "VoiceMail Port"
#!endif
To enhance accounting execute:
enable mysql
define WITH_ACCDB
add following columns to database
define WITH_MYSQL
define WITH_AUTH
define WITH_USRLOCDB
#!ifdef ACCDB_COMMENT
ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';
ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';
ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
#!endif
Value defines – IDs used later in config #!ifdef WITH_MYSQL # – database URL – used to connect to database server by modules such # as: auth_db, acc, usrloc, a.s.o.
disable TCP (default on)
#disable_tcp=yes
enable_sctp = 0
disable the auto discovery of local aliases based on reverse DNS on IPs (default on)
#auto_aliases=no
add local domain aliases #alias=”sip.mydomain.com”
//port to listen
port=5060
#!ifdef WITH_TLS
enable_tls=yes
#!endif
Life time of TCP connection when there is no traffic – a bit higher than registration expires to cope with UA behind NAT
Modules Section
set paths to location of modules (to sources or installation folders)
----- mi_fifo params -----
#modparam("mi_fifo", "fifo_name", "/var/run/kamailio/kamailio_fifo")
----- ctl params -----
#modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl")
----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 30sec
modparam("tm", "fr_timer", 30000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)
----- rr params -----
# set next param to 1 to add value to ;lr param (helps with some UAs)
modparam("rr", "enable_full_lr", 0)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)
registrar params
modparam("registrar", "method_filtering", 1)
/* uncomment the next line to disable parallel forking via location */
# modparam("registrar", "append_branches", 0)
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
# max value for expires of registrations
modparam("registrar", "max_expires", 3600)
# set it to 1 to enable GRUU
modparam("registrar", "gruu_enabled", 0)
usrloc params – enable DB persistency for location entries
Note: leaving NAT pings turned off here as nathelper is <em>only</em> being used for WebSocket connections. NAT pings are not needed as WebSockets have their own keep-alives.
Routing Logic
Main SIP request routing logic processing of any incoming SIP request starts with this route . Read more on Kamailio Call routing and Control
request_route {
# per request initial checks
route(REQINIT);
#!ifdef WITH_WEBSOCKETS
if (nat_uac_test(64)) {
force_rport();
if (is_method("REGISTER")) {
fix_nated_register();
} else {
fix_nated_contact();
if (!add_contact_alias()) {
xlog("L_ERR", "Error aliasing contact \n");
sl_send_reply("400", "Bad Request");
exit;
}
}
}
#!endif
# NAT detection
route(NATDETECT);
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
}
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
# handle retransmissions
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
# authentication
route(AUTH);
# record routing for dialog forming requests (in case they are routed) - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
setflag(FLT_ACC); # do accounting
}
# dispatch requests to foreign domains
route(SIPOUT);
### requests for my local domains
# handle presence related requests
route(PRESENCE);
# handle registrations
route(REGISTRAR);
if ($rU==$null) {
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# dispatch destinations to PSTN
route(PSTN);
# user location service
route(LOCATION);
}
Wrapper for relaying requests
enable additional event routes for forwarded requests – serial forking, RTP relaying handling, a.s.o.
route[RELAY] {
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route"))
t_on_branch("MANAGE_BRANCH");
}
if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("onreply_route"))
t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route"))
t_on_failure("MANAGE_FAILURE");
}
if (!t_relay()) {
sl_reply_error();
}
exit;
}
Per SIP request initial checks
route[REQINIT] {
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(is_method("OPTIONS") && uri==myself &&; $rU==$null) {
sl_send_reply("200","Keepalive");
exit;
}
if(!sanity_check("1511", "7")) {
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
}
Handle requests within SIP dialogs
sequential request withing a dialog should take the path determined by record-routing
route[WITHINDLG] {
if (!has_totag()) return;
if (has_totag()) {
if (loose_route()) {
#!ifdef WITH_WEBSOCKETS
if ($du == "") {
if (!handle_ruri_alias()) {
xlog("L_ERR", "Bad alias <$ru>\n");
sl_send_reply("400", "Bad Request");
exit;
}
}
#!endif
}
exit;
}
if (loose_route()) {
route(DLGURI);
if (is_method("BYE")) {
setflag(FLT_ACC); # do accounting ...
setflag(FLT_ACCFAILED); # ... even if the transaction fails
}
else if ( is_method("ACK") ) {
# ACK is forwarded statelessy
route(NATMANAGE);
}
else if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
exit;
}
if (is_method("SUBSCRIBE") && uri == myself) {
# in-dialog subscribe requests
route(PRESENCE);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# no loose-route, but stateful ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream server
route(RELAY);
exit;
} else {
# ACK without matching transaction ... ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
exit;
}
Handle SIP registrations
tbd
User location service
route[LOCATION] {
#!ifdef WITH_SPEEDDIAL
# search for short dialing - 2-digit extension
if($rU=~"^[0-9][0-9]$")
if(sd_lookup("speed_dial"))
route(SIPOUT);
#!endif
#!ifdef WITH_ALIASDB
# search in DB-based aliases
if(alias_db_lookup("dbaliases"))
route(SIPOUT);
#!endif
$avp(oexten) = $rU;
if (!lookup("location")) {
$var(rc) = $rc;
route(TOVOICEMAIL);
t_newtran();
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found");
exit;
case -2:
send_reply("405", "Method Not Allowed");
exit;
}
}
# when routing via usrloc, log the missed calls also
if (is_method("INVITE")) {
setflag(FLT_ACCMISSED);
}
route(RELAY);
exit;
}
Presence processing
route[PRESENCE] {
if(!is_method("PUBLISH|SUBSCRIBE"))
return;
if(is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
route(TOVOICEMAIL);
# returns here if no voicemail server is configured
sl_send_reply("404", "No voicemail service");
exit;
}
#!ifdef WITH_PRESENCE
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(is_method("PUBLISH")) {
handle_publish();
t_release();
} else if(is_method("SUBSCRIBE")) {
handle_subscribe();
t_release();
}
exit;
#!endif
# if presence enabled, this part will not be executed
if (is_method("PUBLISH") || $rU==$null) {
sl_send_reply("404", "Not here");
exit;
}
return;
}
IP authorization and user authentication
route[AUTH] {
#!ifdef WITH_AUTH
#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address()) {
# source IP allowed
return;
}
#!endif
if (is_method("REGISTER") || from_uri==myself)
{
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (from_uri!=myself && uri!=myself) {
sl_send_reply("403","Not relaying");
exit;
}
#!endif
return;
}
failure_route[MANAGE_FAILURE] {
route(NATMANAGE);
if (t_is_canceled()) {
exit;
}
#!ifdef WITH_BLOCK3XX
# block call redirect based on 3xx replies.
if (t_check_status("3[0-9][0-9]")) {
t_reply("404","Not found");
exit;
}
#!endif
#!ifdef WITH_VOICEMAIL
# serial forking - route to voicemail on busy or no answer (timeout)
if (t_check_status("486|408")) {
$du = $null;
route(TOVOICEMAIL);
exit;
}
#!endif
}
Supports pseudo-variables to access and manage parts of the SIP messages and attributes specific to users and server. Transformations to modify existing pseudo-variables, accessing only the wanted parts of the information.
Already has over 1000 parameters, variables and functions exported to config file. Supports runtime update framework – to avoid restarting the SIP server when needing to change the config parameters.
Manage kamailio from command line, providing lots of operations, such as adding/removing/updating SIP users, controlling the ACL for users, managing the records for LCR or load balancing, viewing registered users and internal statistics, etc.
When needed to interact with Kamailio, it does it via FIFO file created by mi_fifo module.
The tool can be used to create and manage the database structure needed by Kamailio, therefore it should be immediately after Kamailio installation, in case you plan to run Kamailio with a database backend.
Kamailio is a SIP server which does not play any role by itself in media transmission path. this behaviour leads to media packets having to attempt to stream peer to peer between caller and callee which in turn many a times causes them to get dropped in absence of NAT management
To ensure that media stream is proxied via an RTP proxy kamailio can use RTP proxy module combined with a RTP proxy.
This setup also provides other benefits such as controlling media media , security , Load balancing between many rtp proxies ,bridge signalling between multiple network interfaces etc.
RTP Proxy module
Used to proxy the media stream .
RTP proxies that can be used along with this module are:
rtpproxy_disable_tout – when rtp proxy is disabled then timeout till when it doesnt connect
rtpproxy_tout – timeout to wait for reply
rtpproxy_retr – num of retries after timeout
nortpproxy_str – sets the SDP attribute used by rtpproxy to mark the message’s SDP attachment with information that it have already been changed. Default value is
“a=nortpproxy:yes\r\n”
and others like
“a=sdpmangled:yes\r\n”
timeout_socket (string)
ice_candidate_priority_avp (string)
extra_id_pv (string)
db_url (string)
table_name (string)
rtp_inst_pvar (string)
Functions
set_rtp_proxy_set(setid) – Sets the Id of the rtpproxy set to be used for the next unforce_rtp_proxy(), rtpproxy_offer(), rtpproxy_answer() or rtpproxy_manage() command
rtpproxy_offer([flags [, ip_address]]) – to make the media pass through RTP the SDP is altered. Value of flag can be 1 – append first Via branch to Call-ID when sending command to rtpproxy. 2 – append second Via branch to Call-ID when sending command to rtpproxy. See flag ‘1’ for its meaning. 3 – behave like flag 1 is set for a request and like flag 2 is set for a reply a – flags that UA from which message is received doesn’t support symmetric RTP. (automatically sets the ‘r’ flag) b – append branch specific variable to Call-ID when sending command to rtpproxy l – force “lookup”, that is, only rewrite SDP when corresponding session already exists in the RTP proxy i, e – direction of the SIP message when rtpproxy is running in bridge mode. ‘i’ is internal network (LAN), ‘e’ is external network (WAN). Values ie , ei , ee and ii x – shortcut for using the “ie” or “ei”-flags, to do automatic bridging between IPv4 on the “internal network” and IPv6 on the “external network”. Differentiated by IP type in the SDP, e.g. a IPv4 Address will always call “ie” to the RTPProxy (IPv4(i) to IPv6(e)) and an IPv6Address will always call “ei” to the RTPProxy (IPv6(e) to IPv4(i)) f – instructs rtpproxy to ignore marks inserted by another rtpproxy in transit to indicate that the session is already gone through another proxy. Allows creating a chain of proxies r – IP address in SDP should be trusted. Without this flag, rtpproxy ignores address in the SDP and uses source address of the SIP message as media address which is passed to the RTP proxy o – flags that IP from the origin description (o=) should be also changed. c – flags to change the session-level SDP connection (c=) IP if media-description also includes connection information. w – flags that for the UA from which message is received, support symmetric RTP must be forced. zNN – perform re-packetization of RTP traffic coming from the UA which has sent the current message to increase or decrease payload size per each RTP packet forwarded if possible. The NN is the target payload size in ms, for the most codecs its value should be in 10ms increments, however for some codecs the increment could differ (e.g. 30ms for GSM or 20ms for G.723). ip_address denotes the address of new SDP
such as : rtpproxy_offer(“FRWOC+PS”) is rtpengine_offer(“force trust-address symmetric replace-origin replace-session-connection ICE=force RTP/SAVPF”);
route {
...
if (is_method("INVITE"))
{
if (has_body("application/sdp"))
{
if (rtpproxy_offer()) t_on_reply("1");
} else {
t_on_reply("2");
}
}
if (is_method("ACK") && has_body("application/sdp")) rtpproxy_answer();
...
}
onreply_route[1] {
if (has_body("application/sdp")) rtpproxy_answer();
}
onreply_route[2] {
if (has_body("application/sdp")) rtpproxy_offer();
}
rtpproxy_answer([flags [, ip_address]])- rewrite SDP to proxy media , it can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
rtpproxy_destroy([flags]) – tears down RTP proxy session for current call. Flags are , 1 – append first Via branch to Call-ID 2 – append second Via branch to Call-ID b – append branch specific variable to Call-ID t – do not include To tag to “delete” command to rtpproxy thus causing full call to be deleted
unforce_rtp_proxy()
rtpproxy_manage([flags [, ip_address]]) – Functionality is to use predfined logic for handling requests If INVITE with SDP, then do rtpproxy_offer() If INVITE with SDP, when the tm module is loaded, mark transaction with internal flag FL_SDP_BODY to know that the 1xx and 2xx are for rtpproxy_answer() If ACK with SDP, then do rtpproxy_answer() If BYE or CANCEL, or called within a FAILURE_ROUTE[], then call unforce_rtpproxy(). If reply to INVITE with code >= 300 do unforce_rtpproxy() If reply with SDP to INVITE having code 1xx and 2xx, then do rtpproxy_answer() if the request had SDP or tm is not loaded, otherwise do rtpproxy_offer() This function can be used from ANY_ROUTE.
rtpproxy_stream2uac(prompt_name, count) – stream prompt/announcement pre-encoded with the makeann command. The uac/uas suffix selects who will hear the announcement relatively to the current transaction – UAC or UAS. Also used for music on hold (MOH). Params : prompt_name – path name of the prompt to stream count – number of times the prompt should be repeated. When count is -1, the streaming will be in loop indefinitely until the appropriate rtpproxy_stop_stream2xxx is issued. Example rtpproxy_stream2xxx usage
if (is_method("INVITE")) { rtpproxy_offer(); if (is_audio_on_hold()) { rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", "-1"); } else { rtpproxy_stop_stream2uas(); }; };
rtpproxy_stream2uas(prompt_name, count)
rtpproxy_stop_stream2uac()- Stop streaming of announcement/prompt/MOH