Category Archives: SIP servers


Asterisk is a framework or toolkit designed for VOIP systems . It can support Enterprise communication systems like PBXs, call distributors, VoIP gateways , conference bridges etc . It is open source and free to use . It is developed in C and runs in linux .

Technically , Asterisk has protocol support for many telephony technologies and protocols such as SIP , H323 .
It can connect old PSTN or copper line and VOIP .

Asterisk is a framework for building multi-protocol, real-time communications applications and solutions. Asterisk is to realtime voice and video applications as what Apache is to web applications


Combine the SIP channel, the PSTN interface channel and some Dialplan script and you have a gateway.
Change the Dialplan to drop calls into a ConfBridge session and you have a conference server.
Alter it once more to route calls into voice mailboxes and you have a voicemail server.
Tie it all together and you have an amazingly powerful phone system.



goto /usr/src and download the preferred the version of asterisk code from

I am using the latest release candidate at the time writing this article

Some external Dependencies
apt-get install subversion

Then install the source dependencies

 sudo su

This will install mp3 related programs such as

A addons/mp3
A addons/mp3/decode_ntom.c
A addons/mp3/interface.c
A addons/mp3/MPGLIB_README
A addons/mp3/common.c
A addons/mp3/huffman.h
A addons/mp3/tabinit.c
A addons/mp3/Makefile
A addons/mp3/README
A addons/mp3/decode_i386.c
A addons/mp3/dct64_i386.c
A addons/mp3/MPGLIB_TODO
A addons/mp3/mpg123.h
A addons/mp3/layer3.c
A addons/mp3/mpglib.h
Exported revision 202.

Actual dependencies will be installed via install_prereq script

contrib/scripts/install_prereq install

Output snippet

The following NEW packages will be installed:
autoconf{a} automake{a} autopoint{a} autotools-dev{a} binutils{a} binutils-common{a} binutils-dev binutils-x86-64-linux-gnu{a} bison build-essential comerr-dev{a} cpp{a} cpp-7{a} debhelper{a}
dh-autoreconf{a} dh-strip-nondeterminism{a} doxygen dpkg-dev{a} fakeroot{a} flex fontconfig{a} fontconfig-config{a} fonts-dejavu-core{a} fonts-liberation{a} freetds-common{a} freetds-dev g++{a}
g++-7{a} gcc{a} gcc-7{a} gcc-7-base{a} gettext{a} gir1.2-gmime-2.6{a} gir1.2-harfbuzz-0.0{a} graphviz icu-devtools{a} intltool-debian{a} krb5-multidev{a} libalgorithm-diff-perl{a}
libalgorithm-diff-xs-perl{a} libalgorithm-merge-perl{a} libann0{a} libarchive-cpio-perl{a} libarchive-zip-perl{a} libasan4{a} libasound2{a} libasound2-data{a} libasound2-dev libatomic1{a}
libbinutils{a} libbison-dev{a} libbluetooth-dev libbluetooth3{a} libbsd-dev{a} libc-client2007e{a} libc-client2007e-dev libc-dev-bin{a} libc6-dev{a} libcairo2{a} libcc1-0{a} libcdt5{a} libcfg-dev
libcfg6{a} libcgraph6{a} libcilkrts5{a} libclang1-6.0{a} libcodec2-0.7{a} libcodec2-dev libcorosync-common-dev libcorosync-common4{a} libcpg-dev libcpg4{a} libcroco3{a} libct4{a}
libcurl4-openssl-dev libdatrie1{a} libdb-dev{a} libdb5.3-dev{a} libdpkg-perl{a} libedit-dev libexpat1-dev{a} libfakeroot{a} libfftw3-bin{a} libfftw3-dev libfftw3-double3{a} libfftw3-long3{a}
libfftw3-quad3{a} libfftw3-single3{a} libfile-fcntllock-perl{a} libfile-stripnondeterminism-perl{a} libfl-dev{a} libfl2{a} libflac-dev{a} libflac8{a} libfontconfig1{a} libgcc-7-dev{a} libgd3{a}
libglib2.0-bin{a} libglib2.0-dev{a} libglib2.0-dev-bin{a} libgmime-2.6-0{a} libgmime-2.6-dev libgomp1{a} libgpgme11{a} libgraphite2-3{a} libgraphite2-dev{a} libgsm1{a} libgsm1-dev libgssrpc4{a}
libgts-0.7-5{a} libgts-bin{a} libgvc6{a} libgvpr2{a} libharfbuzz-dev{a} libharfbuzz-gobject0{a} libharfbuzz-icu0{a} libharfbuzz0b{a} libical-dev libical3{a} libice6{a} libicu-dev{a}
libicu-le-hb-dev{a} libicu-le-hb0{a} libiculx60{a} libiksemel-dev libiksemel3{a} libisl19{a} libitm1{a} libjack-jackd2-0{a} libjack-jackd2-dev libjansson-dev libjansson4{a} libjbig-dev{a}
libjbig0{a} libjpeg-dev{a} libjpeg-turbo8{a} libjpeg-turbo8-dev{a} libjpeg8{a} libjpeg8-dev{a} libkadm5clnt-mit11{a} libkadm5srv-mit11{a} libkdb5-9{a} liblab-gamut1{a} libldap2-dev libllvm6.0{a}
liblsan0{a} libltdl-dev{a} libltdl7{a} liblua5.2-0{a} liblua5.2-dev liblzma-dev{a} libmail-sendmail-perl{a} libmpc3{a} libmpx2{a} libmysqlclient-dev libmysqlclient20{a} libncurses5-dev{a}
libneon27{a} libneon27-dev libnewt-dev libodbc1{a} libogg-dev libogg0{a} libosptk-dev libosptk4{a} libpam0g-dev{a} libpango-1.0-0{a} libpangocairo-1.0-0{a} libpangoft2-1.0-0{a} libpathplan4{a}
libpcap0.8-dev{a} libpci-dev{a} libpcre16-3{a} libpcre3-dev{a} libpcre32-3{a} libpcrecpp0v5{a} libpixman-1-0{a} libpng-dev{a} libpng-tools{a} libpopt-dev libportaudio2{a} libportaudiocpp0{a}
libpq-dev libpq5{a} libpython-dev{a} libpython-stdlib{a} libpython2.7{a} libpython2.7-dev{a} libpython2.7-minimal{a} libpython2.7-stdlib{a} libqb-dev{a} libqb0{a} libquadmath0{a} libradcli-dev
libradcli4{a} libreadline-dev{a} libresample1{a} libresample1-dev libsamplerate0{a} libsensors4{a} libsensors4-dev{a} libslang2-dev{a} libsm6{a} libsndfile1{a} libsndfile1-dev libsnmp-base{a}
libsnmp-dev libsnmp30{a} libspandsp-dev libspandsp2{a} libspeex-dev libspeex1{a} libspeexdsp-dev libspeexdsp1{a} libsqlite3-dev libsrtp0{a} libsrtp0-dev libsrtp2-1{a} libsrtp2-dev libssl-dev
libssl-doc{a} libstdc++-7-dev{a} libsybdb5{a} libsys-hostname-long-perl{a} libthai-data{a} libthai0{a} libtiff-dev{a} libtiff5{a} libtiff5-dev{a} libtiffxx5{a} libtinfo-dev{a} libtool{a}
libtool-bin{a} libtsan0{a} libubsan0{a} libudev-dev{a} libunbound-dev libunbound2{a} liburiparser-dev liburiparser1{a} libvorbis-dev libvorbis0a{a} libvorbisenc2{a} libvorbisfile3{a} libvpb-dev
libvpb1{a} libwebp6{a} libwrap0-dev{a} libxaw7{a} libxcb-render0{a} libxcb-shm0{a} libxml2-dev libxmu6{a} libxpm4{a} libxrender1{a} libxslt1-dev libxt6{a} linux-libc-dev{a} m4{a} make{a}
manpages-dev{a} mlock{a} module-assistant{a} mysql-common{a} odbcinst{a} odbcinst1debian2{a} pkg-config pkgconf{b} po-debconf{a} portaudio19-dev python{a} python-dev python-minimal{a} python2.7{a}
python2.7-dev{a} python2.7-minimal{a} python3-distutils{a} python3-lib2to3{a} unixodbc-dev uuid-dev vpb-driver-source{a} x11-common{a} xmlstarlet zlib1g-dev
The following packages will be upgraded:
gcc-8-base libcom-err2 libcurl4 libglib2.0-0 libgssapi-krb5-2 libk5crypto3 libkrb5-3 libkrb5support0 libldap-2.4-2 libldap-common libpython3-stdlib libpython3.6-minimal libpython3.6-stdlib
libssl1.1 libudev1 libuuid1 python3 python3-minimal python3.6 python3.6-minimal

Current status: 127 (-25) upgradable.
# ###########################
install completed successfully
# ############################

Run configure which will create scripts for next processes


Build third party scripts

make -j2

After build , to run the installation

make install

Asterisk PBX setup

make basic-pbx

The output should be

Installing basic-pbx config files…
Installing file configs/basic-pbx/README
Installing file configs/basic-pbx/asterisk.conf
Installing file configs/basic-pbx/cdr.conf
Installing file configs/basic-pbx/cdr_custom.conf
Installing file configs/basic-pbx/confbridge.conf
Installing file configs/basic-pbx/extensions.conf
Installing file configs/basic-pbx/indications.conf
Installing file configs/basic-pbx/logger.conf
Installing file configs/basic-pbx/modules.conf
Installing file configs/basic-pbx/musiconhold.conf
Installing file configs/basic-pbx/pjsip.conf
Installing file configs/basic-pbx/voicemail.conf
Updating asterisk.conf

Also run make config to make pbx configs

make config 

start asterisk

systemctl start asterisk

connect to asterisk tool for cli

asterisk -vvvr
Asterisk 16.2.0-rc1, Copyright (C) 1999 - 2018, Digium, Inc. and others.
Created by Mark Spencer
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under

certain conditions. Type 'core show license' for details.

Connected to Asterisk 16.2.0-rc1 currently running on ip-172-31-45-26 (pid = 13388)

SIP and PJSIP modules

module show like sip
Module Description Use Count Status Support Level PJSIP Channel Driver 0 Running core Get information about a PJSIP endpoint 0 Running core Basic SIP resource 38 Running core PJSIP ACL Resource 0 Running core PJSIP authentication resource 0 Running core PJSIP Caller ID Support 1 Running core PJSIP Extension State Dialog Info+XML Pr 0 Running core PJSIP Add Diversion Header Support 0 Running core PJSIP DTMF INFO Support 0 Running core PJSIP Anonymous endpoint identifier 0 Running core PJSIP IP endpoint identifier 0 Running core PJSIP username endpoint identifier 0 Running core PJSIP Extension State Notifications 0 Running core PJSIP Header Functions 0 Running core PJSIP Packet Logger 0 Running core PJSIP Messaging Support 0 Running core PJSIP MWI resource 0 Running core PJSIP MWI resource 0 Running core PJSIP NAT Support 0 Running core CLI/AMI PJSIP NOTIFY Support 0 Not Running core PJSIP INFO One Touch Recording Support 0 Running core PJSIP authentication resource 0 Running core PJSIP Outbound Publish Support 2 Running core PJSIP Outbound Registration Support 0 Running core PJSIP Path Header Support 0 Running core PJSIP Extension State PIDF Provider 0 Running core PJSIP PIDF Digium presence supplement 0 Running core PJSIP PIDF Eyebeam supplement 0 Running core PJSIP Asterisk Event PUBLISH Support 0 Running core PJSIP event resource 11 Running core PJSIP Blind and Attended Transfer Suppor 1 Running core PJSIP Registrar Support 0 Running core PJSIP RFC3326 Support 0 Running core PJSIP SDP RTP/AVP stream handler 0 Running core PJSIP REFER Send to Voicemail Support 0 Running core PJSIP Session resource 14 Running core PJSIP T.38 UDPTL Support 0 Running core PJSIP WebSocket Transport Support 0 Not Running core PJSIP Extension State PIDF Provider 0 Running core
39 modules loaded

Register sip phones with asterisk PBX and make / receive calls

To make calls among users, we need to configure channel driver with sip support . Using the sip protcol the phones within the enterprise will be able to send call signals out to one another. Open pjsip.conf

Take any endpoint from template , such as

;Laverne Roberts
;Software Engineer
[1113 (endpoint-internal-d70)
auth = 1113
aors = 1113
callerid = Laverne Roberts <1113>
[1113 (auth-userpass)
password = xxxxxxxx
username = xxxxxxxx
[1113 (aor-single-reg)
mailboxes = 1113@example

and set the values in sip softphone like zoiper , register with provided creds

registering sip phone zoiper with newly created asterisk PBX

If the registration creds used are not matching with the ones defines in pjsip.conf then REGISTER request failed message is displayed

Request 'REGISTER' from '' failed for 'x.x.x.x:18475' (callid: hp8iN6oWLRdER4zvEBdiUg..) - No matching endpoint found

On correct creds used the server prints traces such as

-- Added contact 'sip:1113@x.x.x.x:44312;transport=UDP;rinstance=b8aceff08623b51e' to AOR '1113' with expiration of 60 seconds
== Endpoint 1113 is now Reachable
-- Removed contact 'sip:1113@x.x.x.x:44312;transport=UDP;rinstance=b8aceff08623b51e' from AOR '1113' due to request
== Contact 1113/sip:1113@x.x.x.x:44312;transport=UDP;rinstance=b8aceff08623b51e has been deleted
== Endpoint 1113 is now Unreachable
-- Added contact 'sip:1113@x.x.x.x:18475;transport=UDP;rinstance=5af431512ae0af3a' to AOR '1113' with expiration of 60 seconds
== Endpoint 1113 is now Reachable

Alternatively one can also create new sip endpoints


core show help
! -- Execute a shell command
acl show -- Show a named ACL or list all named ACLs
aoc set debug -- enable cli debugging of AOC messages
bridge kick -- Kick a channel from a bridge
bridge show all -- List all bridges
bridge show -- Show information about a bridge
bridge technology show -- List registered bridge technologies
bridge technology {suspend|unsuspend} -- Suspend/unsuspend a bridge technology
cc cancel [core|all] -- Kill a CC transaction
cc report status -- Reports CC stats
cdr set debug [on|off] -- Enable debugging in the CDR engine
cdr show active -- Display active CDRs for channels
cdr show status -- Display the CDR status
cdr submit -- Posts all pending batched CDR data
cel show status -- Display the CEL status
channel request hangup -- Request a hangup on a given channel
cli check permissions -- Try a permissions config for a user
cli reload permissions -- Reload CLI permissions config
cli show permissions -- Show CLI permissions
confbridge kick -- Kick participants out of conference bridges.
confbridge list -- List conference bridges and participants.
confbridge lock -- Lock a conference.
confbridge mute -- Mute participants.
confbridge record start -- Start recording a conference
confbridge record stop -- Stop recording a conference.
confbridge show menu -- Show a conference menu
confbridge show menus -- Show a list of conference menus
confbridge show profile bridge -- Show a conference bridge profile.
confbridge show profile bridges -- Show a list of conference bridge profiles.
confbridge show profile user -- Show a conference user profile.
confbridge show profile users -- Show a list of conference user profiles.
confbridge unlock -- Unlock a conference.
confbridge unmute -- Unmute participants.
config list -- Show all files that have loaded a configuration file
config reload -- Force a reload on modules using a particular configuration file
config show help -- Show configuration help for a module
core abort shutdown -- Cancel a running shutdown
core clear profile -- Clear profiling info
core ping taskprocessor -- Ping a named task processor
core reload -- Global reload
core restart gracefully -- Restart Asterisk gracefully
core restart now -- Restart Asterisk immediately
core restart when convenient -- Restart Asterisk at empty call volume
core set debug channel -- Enable/disable debugging on a channel
core set debug -- Set level of debug chattiness
core set verbose -- Set level of verbose chattiness
core show applications [like|describing] -- Shows registered dialplan applications
core show application -- Describe a specific dialplan application
core show calls [uptime] -- Display information on calls
core show channels [concise|verbose|count] -- Display information on channels
core show channel -- Display information on a specific channel
core show channeltypes -- List available channel types
core show channeltype -- Give more details on that channel type
core show codecs [audio|video|image|text] -- Displays a list of registered codecs
core show codec -- Shows a specific codec
core show config mappings -- Display config mappings (file names to config engines)
core show file formats -- Displays file formats
core show functions [like] -- Shows registered dialplan functions
core show function -- Describe a specific dialplan function
core show hanguphandlers all -- Show hangup handlers of all channels
core show hanguphandlers -- Show hangup handlers of a specified channel
core show help -- Display help list, or specific help on a command
core show hints -- Show dialplan hints
core show hint -- Show dialplan hint
core show image formats -- Displays image formats
core show license -- Show the license(s) for this copy of Asterisk
core show profile -- Display profiling info
core show settings -- Show some core settings
core show sounds -- Shows available sounds
core show sound -- Shows details about a specific sound
core show switches -- Show alternative switches
core show sysinfo -- Show System Information
core show taskprocessors -- List instantiated task processors and statistics
core show threads -- Show running threads
core show translation -- Display translation matrix
core show uptime [seconds] -- Show uptime information
core show version -- Display version info
core show warranty -- Show the warranty (if any) for this copy of Asterisk
core stop gracefully -- Gracefully shut down Asterisk
core stop now -- Shut down Asterisk immediately
core stop when convenient -- Shut down Asterisk at empty call volume
core waitfullybooted -- Wait for Asterisk to be fully booted
database del -- Removes database key/value
database deltree -- Removes database keytree/values
database get -- Gets database value
database put -- Adds/updates database value
database query -- Run a user-specified query on the astdb
database show -- Shows database contents
database showkey -- Shows database contents
devstate change -- Change a custom device state
devstate list -- List currently known custom device states
dialplan add extension -- Add new extension into context
dialplan add ignorepat -- Add new ignore pattern
dialplan add include -- Include context in other context
dialplan debug -- Show fast extension pattern matching data structures
dialplan reload -- Reload extensions and only extensions
dialplan remove context -- Remove a specified context
dialplan remove extension -- Remove a specified extension
dialplan remove ignorepat -- Remove ignore pattern from context
dialplan remove include -- Remove a specified include from context
dialplan set chanvar -- Set a channel variable
dialplan set extenpatternmatchnew false -- Use the Old extension pattern matching algorithm.
dialplan set extenpatternmatchnew true -- Use the New extension pattern matching algorithm.
dialplan set global -- Set global dialplan variable
dialplan show -- Show dialplan
dialplan show chanvar -- Show channel variables
dialplan show globals -- Show global dialplan variables
dnsmgr refresh -- Performs an immediate refresh
dnsmgr reload -- Reloads the DNS manager configuration
dnsmgr status -- Display the DNS manager status
features show -- Lists configured features
group show channels -- Display active channels with group(s)
http show status -- Display HTTP server status
indication add -- Add the given indication to the country
indication remove -- Remove the given indication from the country
indication show -- Display a list of all countries/indications
local show channels -- List status of local channels
logger add channel -- Adds a new logging channel
logger mute -- Toggle logging output to a console
logger reload -- Reopens the log files
logger remove channel -- Removes a logging channel
logger rotate -- Rotates and reopens the log files
logger set level {DEBUG|NOTICE|WARNING|ERROR|VERBOSE|DTMF} {on|off} -- Enables/Disables a specific logging level for this console
logger show channels -- List configured log channels
malloc trim -- Return excess memory to the OS
manager reload -- Reload manager configurations
manager set debug [on|off] -- Show, enable, disable debugging of the manager code
manager show command -- Show a manager interface command
manager show commands -- List manager interface commands
manager show connected -- List connected manager interface users
manager show eventq -- List manager interface queued events
manager show events -- List manager interface events
manager show event -- Show a manager interface event
manager show settings -- Show manager global settings
manager show users -- List configured manager users
manager show user -- Display information on a specific manager user
media cache create -- Create an item in the media cache
media cache delete -- Remove an item from the media cache
media cache refresh -- Refresh an item in the media cache
media cache show all -- Show all items in the media cache
media cache show -- Show a single item in the media cache
module load -- Load a module by name
module reload -- Reload configuration for a module
module show [like] -- List modules and info
module unload -- Unload a module by name
moh reload -- Reload MusicOnHold
moh show classes -- List MusicOnHold classes
moh show files -- List MusicOnHold file-based classes
no debug channel -- Disable debugging on channel(s)
pjproject set log level {default|0|1|2|3|4|5|6} -- Set the maximum active pjproject logging level
pjproject show buildopts -- Show the compiled config of the pjproject in use
pjproject show log level -- Show the maximum active pjproject logging level
pjproject show log mappings -- Show pjproject to Asterisk log mappings
pjsip dump endpt -- Dump the res_pjsip endpt internals
pjsip list aors -- List PJSIP Aors
pjsip list auths -- List PJSIP Auths
pjsip list channels -- List PJSIP Channels
pjsip list ciphers -- List available OpenSSL cipher names
pjsip list contacts -- List PJSIP Contacts
pjsip list endpoints -- List PJSIP Endpoints
pjsip list identifies -- List PJSIP Identifies
pjsip list registrations -- List PJSIP Registrations
pjsip list subscriptions {inbound|outbound} [like] -- List active inbound/outbound subscriptions
pjsip list transports -- List PJSIP Transports
pjsip qualify -- Send an OPTIONS request to a PJSIP endpoint
pjsip reload qualify aor -- Synchronize the PJSIP Aor qualify options
pjsip reload qualify endpoint -- Synchronize the qualify options for all Aors on the PJSIP endpoint
pjsip send register -- Registers an outbound registration target
pjsip send unregister -- Unregisters outbound registration target
pjsip set logger {on|off|host} -- Enable/Disable PJSIP Logger Output
pjsip show aors -- Show PJSIP Aors
pjsip show aor -- Show PJSIP Aor
pjsip show auths -- Show PJSIP Auths
pjsip show auth -- Show PJSIP Auth
pjsip show channels -- Show PJSIP Channels
pjsip show channel -- Show PJSIP Channel
pjsip show channelstats -- Show PJSIP Channel Stats
pjsip show contacts -- Show PJSIP Contacts
pjsip show contact -- Show PJSIP Contact
pjsip show endpoints -- Show PJSIP Endpoints
pjsip show endpoint -- Show PJSIP Endpoint
pjsip show identifiers -- List registered endpoint identifiers
pjsip show identifies -- Show PJSIP Identifies
pjsip show identify -- Show PJSIP Identify
pjsip show qualify aor -- Show the PJSIP Aor current qualify options
pjsip show qualify endpoint -- Show the current qualify options for all Aors on the PJSIP endpoint
pjsip show registrations -- Show PJSIP Registrations
pjsip show registration -- Show PJSIP Registration
pjsip show scheduled_tasks -- Show all scheduled tasks
pjsip show settings -- Show global and system configuration options
pjsip show subscription {inbound|outbound} -- Show active subscription details
pjsip show subscriptions {inbound|outbound} [like] -- Show active inbound/outbound subscriptions
pjsip show transports -- Show PJSIP Transports
pjsip show transport -- Show PJSIP Transport
pjsip show unidentified_requests -- Show PJSIP Unidentified Requests
pjsip show version -- Show the version of pjproject in use
rtcp set debug {on|off|ip} -- Enable/Disable RTCP debugging
rtcp set stats {on|off} -- Enable/Disable RTCP stats
rtp set debug {on|off|ip} -- Enable/Disable RTP debugging
say load [new|old] -- Set or show the say mode
stun set debug {on|off} -- Enable/Disable STUN debugging
timing test -- Run a timing test
udptl set debug {on|off|ip} -- Enable/Disable UDPTL debugging
udptl show config -- Show UDPTL config options
voicemail reload -- Reload voicemail configuration
voicemail show aliases -- List mailbox aliases
voicemail show users [for] -- List defined voicemail boxes
voicemail show zones -- List zone message formats
xmldoc dump -- Dump the XML docs to the specified file

*CLI> core show settings

PBX cores settings 
Version: 16.2.0-rc1
Maximum calls: Not set
Maximum open file handles: 1024
Root console verbosity: 5
Current console verbosity: 5
Debug level: 0
Maximum load average: 0.000000
Minimum free memory: 0 MB
Startup time: 10:27:35
Last reload time: 10:27:35
System: Linux/4.15.0-1021-aws built by root on x86_64 2019-02-11 11:48:29 UTC
System name:
Entity ID: 0e:28:c0:44:39:5e
PBX UUID: a2df96bb-6d1a-4f64-a953-cf02030e9851
Default language: en
Language prefix: Enabled
User name and group: /
Executable includes: Disabled
Transcode via SLIN: Enabled
Transmit silence during rec: Disabled
Generic PLC: Disabled
Generic PLC on equal codecs: Disabled
Min DTMF duration:: 80
Cache media frames: Enabled
RTP use dynamic payloads: 1
RTP dynamic payload types: 35-63,96-127

Manager (AMI): Disabled
Web Manager (AMI/HTTP): Disabled
Call data records: Enabled
Realtime Architecture (ARA): Disabled

Configuration file: /etc/asterisk/asterisk.conf
Configuration directory: /etc/asterisk
Module directory: /usr/lib/asterisk/modules
Spool directory: /var/spool/asterisk
Log directory: /var/log/asterisk
Run/Sockets directory: /var/run/asterisk
PID file: /var/run/asterisk/
VarLib directory: /var/lib/asterisk
Data directory: /var/lib/asterisk
ASTDB: /var/lib/asterisk/astdb
IAX2 Keys directory: /var/lib/asterisk/keys
AGI Scripts directory: /var/lib/asterisk/agi-bin



It is an multi-functional, multi-purpose SIP server especially used in VoIP landscape as standalone SIP server or SBC ( Session Border Controller ) for inbound and outbound traffic by carriers, telecoms backend layers or ITSPs for call routing and trunking solutions. It can be deployed with Class4/5 Platforms, SIP Trunking , hosted or IP PBX setup , existing gateways/ Session Border Controllers, Application Servers, proxy server, Front-End Load Balancers, IMS Platforms, Call Center etc.


Due to its very flexible and customisable routing engine it can be used in number of scenarios such as an SIP proxy or a  router and due to its high throughput it is widely recommended as an enterprise grade inbound/outbound proxy server. Some of the prominent features are,

  • Registrar
  • Router / proxy (lcr, dynamic routing, dialplan features)
  • Redirect server
  • Presence agent
  • Back-to-back User Agent
  • IM server
  • SIP to SMS gateway (bidirectional)
  • SIP to XMPP gateway for presence and IM (bidirectional)
  • Load-balancer or dispatcher
  • Inbound/front end for gateways/asterisk
  • SIP NAT traversal unit
  • Application server with custom logic

I have explained the usage of these server components in my previous article on  SIP entities and Server here

Modular Arhitecture

Opensips has majorly 2 parts core and addon-modules.

Opensips Core part is only a proxy stateless SIP server . It contains

  • SIP transport layer which supports UDP, TCP, TLS and WS for SIP. As per the listener in routing script transport protocols is selected .
  • SIP factory — the message parser and builder which can be used to add new headers or remove existing ones.
  • Routing script parser and interpreter for the routing script which loads it to the memory at the startup time. To load a new script server restart is required.
  • Memory and locking manager for the memory allocation and locking to prevent deadlocks and starvation. Although these arn’t accesible by route scripting, it can be configured at compile time.
  • Core script functions and variables which can be used in routing scripts in addition to the functions exported by add-on modules.


Events Interface

Used to notify external applications about events triggered internal to OpenSIPS such as
core events – E_CORE_THRESHOLD ,E_CORE_PKG_THRESHOLD , E_CORE_SHM_THRESHOLD , modules events , or even a custom event using raise_event() command

Statistics Interface

Provide insights to statistics of opensips in numerical results which could be used for services like  monitoring, load evaluation, realtime integration etc. The statictsics can be of two kinds :
1. counter like – variables that keep counting things that happened in OpenSIPS, like received requests, processed dialogs, failed DB queries, etc
2. computed values – variables that are calculated in realtime, like how much memory is used, the current load, active dialogs, active transactions, etc

These variable would reset form 0 at start sometimes even during runtime.

Binary Internal Interface

Provider communication between individual OpenSIPS instances. Used in cases such as failovers where dialogs needs to persist for service continuity. Hence with this interface one can replicate all the events related to the runtime data (creation / updating / deletion) to a backup OpenSIPS instance.

SQL interface and NoSQL interface

SQL interfaces provides interaction with Sql DB drivers and services such as MySQL, Postgres, Oracle, Berkeley, unixODBC etc , while NoSQL interface provides access to Redis, CouchBase, Cassandra, MongoDB, Memcached, and other databases which are more frequently implemented as external caches.

AAA interface definition

Currently, OpenSIPS supports the RADIUS driver for the AAA interface with upcoming support for DIAMETER.

Management interface

Allows the external applications to trigger predefined commands
Push data like setting a debug level, registering a contact etc
Fetch data like registered users, ongoing calls, get statistics etc
Trigger an internal action as reloading the data, sending a message so on

1. Functional SIP modules

SIP signalling modules such as B2B_ENTITIES , B2B_LOGIC , CALL CENTER ( for Inbound call center system ) , DIALOG , NAT_TRAVERSAL , NATHELPER
TM (Transaction/stateful module) , SL (Stateless replier ) , SMS (SIP-to-SMS IM gateway)

SIP Routing modules such as CARRIERROUTE ( routing extension suitable for carriers) , CPL_C ( Call Processing Langugage interpreter ) ,
JABBER (JABBER IM and PRESENCE interconnection ) , IMC ( Instant Messaging Conferencing ),
LOAD_BALANCER , MSILO (SIP message silo) , RR ( Record-Route) , SCRIPT_HELPER ( Embedded SIP routing logic and dialog management) , OSP ( Open Settlement Protocol )

URI , SST ( SIP Session Timer support )

B2B_SCA ( Back-to-Back Shared Call ), RLS ( Resource List Server )

2. Scripting modules

Script helper modules such as JSON , CFGUTILS , EXEC , TEXTOPS , AVPOPS , REGEX, MATHOPS , BENCHMARK ,
CARRIERROUTE , GFLAGS (Global shared flags )

Auth modules such as AUTH , AUTH_AAA ,AUTH_DB , PERMISSIONS

Accounting & Billing modules aas ACC ,CALL CONTROL

Dialplan Modules like ALIAS_DB , DIALPLAN , DOMAIN ( Multi-domain support ) , DOMAINPOLICY ,


Traffic shaping module as PIKE ( Flood detector module ), QOS ,RATELIMIT ,FRAUD_DETECTION

3. Database modules



4. External Integration modules

EVENT_VIRTUAL ( Aggregator of event backends failover & balancing), EVENT_XMLRPC
MI_DATAGRAM ( DATAGRAM unix and network support for Management Interface )
HTTPD , PI_HTTP ( Provisioning Interface ) , STATISTICS

Media Relays
MEDIAPROXY – NAT traversal module
RTPENGINE – Connector to RTPengine external RTP relay
RTPPROXY – Connector to RTPproxy external RTP relay

non-SIP protocols modules such as AAA_RADIUS , H350 , LDAP – LDAP connector , stable
REST_CLIENT , SEAS ( Sip Express Application Server interface module), SIPCAPTURE , SIPTRACE ,
SNGTC ( Voice Transcoding in OpenSIPS using Sangoma hardware ),
SNMPStats , STUN , XMPP ( SIP-to-XMPP Gateway )

5. OpenSIPS protocols and infrastructure

CLUSTERER , TLS_MGM , PROTO_BIN ( Binary INterface protocol module to implements inter-OPENSIPS communication )

How to Install and use Opensips on your VoIP platform

Install from git repo

git clone opensips_head
install gcc
make all

Install from apt

apt-key adv --keyserver --recv-keys 049AD65B
echo "deb trusty 2.4-releases" >/etc/apt/sources.list.d/opensips.list

check if opensips is running

ps -uax|grep opensips

Configuration ( opensips.cfg )

It has 3 main logical parts :

global parameters – network listeners, available transport protocols, forking (and number of processes), the logging

modules section – the modules that are to be loaded  with path to their .so file

routing logic – logic for routing sip traffic


OpenSIPS routing logic uses several types of routes. Each type of route is triggered by a certain event and allows you to process a certain type of message (request or reply).

  1. route
    SIP requests routing. The main ‘route’ block identified by ‘route{…}’ or ‘route[0]{…}’ is executed for each SIP request.
    To send a reply or forward the request, explicit actions must be called inside the route block. in example below which sends 200 ok reply for each options request.
route {
if(is_method("OPTIONS")) {
sl_send_reply("200", "ok");
route[1] {
  1. branch_route
    Handles different branches of a SIP request. if the branch is not dropped the branch will be automatically sent out. It is executed only by TM module after it was armed via t_on_branch(“branch_route_index”).
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");

or lookup location and discard branches where uri matches ip by using drop()

route {
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
branch_route[op3] {
if(uri=~"1\.2\.3\.4") {
  1. failure_route
    Failed transaction routing block. It contains a set of actions to be taken each transaction that received only negative replies (>=300) for all branches which completes the transaction. The ‘failure_route’ is executed only by TM module after it was armed via t_on_failure(“failure_route_index”).
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");

failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {

or on failure relay to voice mail

route {
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
failure_route[op1] {
if(is_method("INVITE")) {
  1. onreply_route
    Reply routing block. It can be stateful (if bound to a transaction) or stateless (if global reply route).
    If the reply is not dropped (only provisional replies can be), it will be injected and processed by the transaction engine. There are three types of onreply routes:

global – catches all replies and uses simple definition ‘onreply_route {…}’ or ‘onreply_route[0] {…}’.
Exmaple for “global” reply route set the whole transaction

route {
seturi("");  first branch
append_branch("");  second branch

onreply_route {
xlog("OpenSIPS received a reply from $si\n");

onreply_route[global] {
if (t_check_status("1[0-9][0-9]")) {
log("provisional reply received\n");
if (t_check_status("183"))

per request/transaction – it catches all received replies belonging to a certain transaction and uses “t_on_reply()” at request time, in REQUEST ROUTE – named ‘onreply_route[N] {…}’.

per branch – it catches only the replies that belong to a certain branch from a transaction via “t_on_reply()” ) at request time, but in BRANCH ROUTE, when a certain outgoing branch is processed – named ‘onreply_route[N] {…}’.
Certain ‘onreply_route’ blocks can be executed by TM module for special replies. For this, the ‘onreply_route’ must be armed for the SIP requests whose replies should be processed within it, via t_on_reply(“onreply_route_index”).

Exmaple of reply route set for this branch only

branch_route[1] {
if ($rU=="alice")

onreply_route[alice] {
xlog("received reply on the branch from alice\n");

5. error_route

executed automatically on meeting and error such as parsing error in SIP request processing, script assert failure. Performs error handling . The Default action is to discard request. In error_route, the following pseudo-variables are available to get access to error details:

$(err.class) - the class of error (now is '1' for parsing errors)
$(err.level) - severity level for the error
$( - text describing the error
$(err.rcode) - recommended reply code
$(err.rreason) - recommended reply reason phrase
error_route {
xlog("--- error route class=$(err.class) level=$(err.level)
info=$( rcode=$(err.rcode) rreason=$(err.rreason) ---\n");
xlog("--- error from [$si:$sp]\n+++++\n$mb\n++++\n");
sl_send_reply("$err.rcode", "$err.rreason");
  1. local_route

executed automatically as TM created a new request, internally (no UAC side). This is a route intended to be used for message inspection, accounting and for applying last changes on the message headers. Routing and signaling functions are not allowed.

local_route {
if (is_method("INVITE") && $ru=~"") {
append_hf("P-hint: foreign request\r\n");
if (is_method("BYE") ) {
acc_log_request("internally generated BYE");
  1. startup_route
    Executed only once when OpenSIPS is started and before the processing of SIP messages begins. Used in initilization cases cases such as loading some data in the cache.
startup_route {
avp_db_query("select gwlist where ruleid==1",$avp(i:100));
cache_store("local", "rule1", "$avp(i:100)");
  1. timer_route
    Route executed periodically at a configured interval of time specified next to the name(in seconds).
timer_route[gw_update, 300] {
avp_db_query("select gwlist where ruleid==1",$avp(i:100));
$shv(i:100) =$avp(i:100);
  1. event_route
    execute script code when an event is triggered. If no way to handle the event specified, default will be synchronously.
    Triggered by the event_route module when an event is raised by the OpenSIPS Event Interface such as event raised by the pike module when it decides an ip should be blocked called E_PIKE_BLOCKED or E_SCRIPT_EVENT etc ( checke events interface for more events)
event_route[E_PIKE_BLOCKED] {
xlog("The E_PIKE_BLOCKED event was raised\n");
event_route[E_PIKE_BLOCKED, async] {
xlog("The E_PIKE_BLOCKED event was raised\n");

Scripting Language

Opensips scripting provided more advanced controls

1. Core Keywords

Keywords specific to SIP messages which can be used mainly in ‘if’ expressions.
af – address family of the received SIP message. It is INET if the message was received over IPv4 or INET6 if the message was received over IPv6.

if(af==INET6) {
log("Message received over IPv6 link\n");

dst_ip – IP of the local interface where the SIP message was received.

if(dst_ip== {
log("message received on loopback interface\n");

dst_port – local port where the SIP packet was received

log("message was received on port 5061\n");

from_uri – reference to the URI of ‘From’ header.

if(is_method("INVITE") &amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp; from_uri=~".*")
log("the caller is from\n");

method – SIP method of the message.

log("this SIP request is a REGISTER message\n");

msg:len – the size of the message

sl_send_reply("413", "message too large");

$retcode – value returned by last function executed like $?. If tested after a call of a route, it is the value retuned by that route.

route {
log("The request is an INVITE\n");

route[1] {

proto – transport protocol of the SIP message.

log("SIP message received over UDP\n");

status – status code of the reply.

log("this is a 200 OK reply\n");

1.10 src_ip – source IP address

log("the message was sent from localhost!\n");

1.11 src_port – source port of the SIP message (from which port the message was sent by previous hop).

log("message sent from port 5061\n");

1.12 to_uri – URI from To header.

log("this is a request for users\n");

1.13 uri – request URI.

log("this is a request for users\n");

2. Core Values

Values that can be used in ‘if’ expressions to check against Core Keywords

2.1 INET – IPv4 connection.

2.2 INET6 – IPv6 connection.

2.3 TCP

2.4 UDP

2.5 max_len – test message’s size.

sl_send_reply("413", "message too large to be forwarded over UDP without fragmentation");

2.6 myself – reference to the list of local IP addresses, hostnames and aliases that has been set in OpenSIPS configuration file. This lists contain the domains served by OpenSIPS.

if(uri==myself) {
log("the request is for local processing\n");

2.7 null – reset the value of a per-script variable or to delete an avp.

$avp(i:12) = null;
$var(x) = null;

3. Core parameters

3.1 abort_on_assert – Set to true in order to make OpenSIPS shut down immediately in case a script assert fails.

abort_on_assert = true // default is false

3.2 advertised_address – address advertised in Via header and other destination lumps (e.g RR header).

3.3 advertised_port – port advertised in Via header and other destination lumps (e.g. RR).

3.4 alias – set alias hostnames for the server

3.5 auto_aliases – to control if aliases should be automatically discovered from DNS lookup and added during fixing listening sockets.

auto_aliases=no // default value is no

3.8 cfg_file – Returns the name of the corresponding OpenSIPS config file

3.9 cfg_line – corresponding line inside the OpenSIPS config file.
3.10 check_via – Check if the address in top most via of replies is local.

check_via=1 // Default value is 0 (check disabled)

3.11 children – Number of worker processes (children) to be created for each UDP or SCTP interface you have defined.

children=16 // Default value is 8
3.12 chroot – If set, OpenSIPS will chroot (change root directory) to this valid path in the system value.


3.13 debug_mode – This option will automatically force:

staying in foreground
set logging level to 4 (debug)
set logging to standard error
enable core dumping
set UDP worker processes to 2
set TCP worker processes to 2
Default value is false/0 (disabled).
3.14 db_version_table
The name of the table version to be used by the DB API to check the version of the used tables. Default value is “version”


3.15 db_default_url – default DB URL to be used by modules if no per-module URL is given.


3.16 db_max_async_connections – Maximum number of TCP connections opened from a single OpenSIPS worker to each individual SQL backend. Default value is 10.
Individual backends are determined from DB URLs as follows: [ scheme, user, pass, host, port, database ]


3.18 disable_503_translation – If ‘yes’, OpenSIPS will not translate the received 503 replies into 500 replies .
Default value is ‘no’ (do translation as per RFC 3261).
3.19 disable_core_dump – By default core dump limits are set to unlimited or a high enough value. Set this config variable to ‘yes’ to disable core dump-ing (will set core limits to 0).

disable_core_dump=yes //Default value is 'no'.

3.20 disable_dns_blacklist
The DNS resolver, when configured with failover, can automatically store in a temporary blacklist the failed destinations. This will prevent (for a limited period of time) OpenSIPS to send requests to destination known as failed. So, the blacklist can be used as a memory for the DNS resolver.

The temporary blacklist created by DNS resolver is named “dns” and it is by default selected for usage (no need use the use_blacklist()) function. The rules from this list have a life time of 4 minutes – you can change it at compile time, from resolve.c . Can be ‘yes’ or ‘no’. By default the blacklist is disabled (Default value is ‘yes’).

3.21 disable_dns_failover – By default DNS-based failover is enabled. Set this config variable to ‘yes’ to disable the DNS-based failover. This is a global option, affecting the core and the modules also.


3.22 disable_stateless_fwd
Can be ‘yes’ or ‘no’. This parameter controls the handling of stateless replies:

yes – drop stateless replies if stateless fwd functions (like forward) are not used in script
no – forward stateless replies
Default value is ‘yes’.

3.23 dns – controls if the SIP server should attempt to lookup its own domain name in DNS. Default is no.

3.24 dns_retr_time – Time in seconds before retrying a dns request. Default value is system specific, depends also on the ‘/etc/resolv.conf’ content (usually 5s).


3.25 dns_retr_no – Number of dns retransmissions before giving up.


3.26 dns_servers_no – How many dns servers from the ones defined in ‘/etc/resolv.conf’ will be used. Default value is to use all of them.


3.27 dns_try_ipv6 – If it is set to ‘yes’ and a DNS lookup fails, it will retry it for ipv6 (AAAA record). Default value is ‘no’.


3.28 dns_try_naptr – Disables the NAPTR lookups when doing DNS based routing for SIP requests – if disabled, the DNS lookup will start with SRV lookups. By default it is enabled, value ‘yes’.


3.29 dns_use_search_list


3.30 dst_blacklist – static (read-only) IP/destination blacklist. These lists can be selected from script (at runtime) to filter the outgoing requests, based on IP, protocol, port, etc.

filter out requests going to ips of my gws
dst_blacklist = gw:{( tcp , , 5060 , “” ),( any , , 0 , “” )}

block requests going to “evil” networks
dst_blacklist = net_filter:{ ( any , , 0 , “” )}

block message requests with nasty words
dst_blacklist = msg_filter:{ ( any , , 0 , “MESSAGE*ugly_word” )}

block requests not going to a specific subnet
dst_blacklist = net_filter2:{ !( any , , 0 , “” )}

Each rule is defined by:

protocol : TCP, UDP, TLS or “any” for anything
port : number or 0 for any
test patter – is a filename like matching (see “man 3 fnmatch”) applied on the outgoing request buffer (first_line+hdrs+body)

3.31 enable_asserts – Set to true in order to enable the assert script statement.

enable_asserts = true

3.32 event_pkg_threshold – A number representing the percentage threshold above which the E_CORE_PKG_THRESHOLD event is raised, warning about low amount of free private memory. It accepts integer values between 0 and 100. Default value is 0 ( event disabled ).

event_pkg_threshold = 90

3.33 event_shm_threshold
A number representing the percentage threshold above which the E_CORE_SHM_THRESHOLD event is raised, warning about low amount of free shared memory. It accepts integer values between 0 and 100.
Default value is 0 ( event disabled ).

event_shm_threshold = 90

3.34 exec_dns_threshold – A number representing the maximum number of microseconds a DNS query is expected to last. Anything above the set number will trigger a warning message to the logging facility. Default value is 0 ( logging disabled ).
exec_dns_threshold = 60000

3.35 exec_msg_threshold – A number representing the maximum number of microseconds the processing of a SIP msg is expected to last. Anything above the set number will trigger a warning message to the logging facility. Aside from the message and the processing time, the most time consuming function calls from the script will also be logged.

Default value is 0 ( logging disabled ).

exec_msg_threshold = 60000
3.38 include_file – load additional routes/blocks with file path

include_file “proxy_regs.cfg”

3.39 import_file – Same as include_file but will not throw an error if file is not found.

import_file “proxy_regs.cfg”

3.40 listen – Set the network addresses the SIP server should listen to. Its syntax is protocol:address[:port], where:

protocol: should be one of the transport modules loaded in the config file (e.g., udp, tcp, tls)
address: can be an IP address, a hostname, a network interface id, or the * wildcard which makes OpenSIPS listen on all possible interfaces for that protocol
port: optional, the port used by the listener – if absent, the default port exported by the transport module is used.
This parameter can be set multiple times in same configuration file, the server listening on all addresses specified.

The listen definition may accept several optional parameters for:

configuring an advertised IP and port only for an interface. Syntax “AS”
setting a different number of children for this interface only (for UDP, SCTP and HEP_UDP interfaces only). This will override the global “children” parameter. Syntax “use_children 5”
Remember that the above parameters only affect the interface they are configured for; if they are not defined for a given interface, the global values will be used instead.

listen = udp:*
listen = udp:eth1
listen = tcp:eth1:5062
listen = tls:localhost:5061
listen = hep_udp:
listen = ws: use_children 5
listen = sctp: as use_children 3
On startup, OpenSIPS reports all the interfaces that it is listening on. The TCP engine processes will be created regardless if you specify only UDP interfaces here.
3.41 log_facility – control the facility for logging in syslog. Default value is LOG_DAEMON.


3.42 log_level – logging level (how verbose OpenSIPS should be). Higher values make OpenSIPS to print more messages.

log_level=1 — print only important messages (like errors or more critical situations) recommended for running proxy as daemon
log_level=4 — print a lot of debug messages use it only when doing debugging sessions

Actual values are:

-3 – Alert level
-2 – Critical level
-1 – Error level
1 – Warning level
2 – Notice level
3 – Info level
4 – Debug level
The ‘log_level’ parameter is usually used in concordance with ‘log_stderror’ parameter.

Value of ‘log_level’ parameter can also be get and set dynamically using log_level Core MI function or $log_level script variable.
3.43 log_name – Set the id to be printed in syslog. The value must be a string and has effect only when OpenSIPS runs in daemon mode (fork=yes), after daemonize. Default value is argv[0].


3.44 log_stderror – write log messages to standard error. Possible values are:
– “yes” – write the messages to standard error
– “no” – write the messages to syslog , also the default
3.45 max_while_loops – maximum loops that can be done within a “while”. Comes as a protection to avoid infinite loops in config file execution. Default is 100.


3.46 maxbuffer – size in bytes not to be exceeded during the auto-probing procedure of discovering the maximum buffer size for receiving UDP messages. Default value is 262144.


3.47 mem-group – Defines a group of modules (by name) to get separate memory statistics.In order for the feature to work you have to run “make generate-mem-stats” and complile with the variable SHM_EXTRA_STATS defined and complile with the variable SHM_SHOW_DEFAULT_GROUP definedwill generate the statistics for the default group

mem-group = “interest”: “core” “tm”
mem-group = “runtime”: “dialog” “usrloc” “tm”
3.48 mem_warming – Only relevant when the HP_MALLOC compile flag is enabled. If set to “on”, on each startup, OpenSIPS will attempt to restore the memory fragmentation pattern it had before the stop/restart.
Default value: off
Memory warming is useful when dealing with high volumes of traffic (thousands of cps on multi-core machines – the more cores, the more useful), because processes must mutually exclude themselves when chopping up the initial big memory chunk. By performing fragmentation on startup, OpenSIPS will also behave optimally in the first minute(s) after a restart. Fragmentation usually lasts a few seconds (e.g. ~5 seconds on an 8GB shm pool and 2.4Ghz CPU) – traffic will not be processed at all during this period.

mem_warming = on

3.49 mem_warming_percentage – How much of OpenSIPS’s memory should be fragmented with the pattern of the previous run, upon a restart.

mem_warming_percentage = 50 //Default value: 75

3.50 mem_warming_pattern_file – Default value: “CFG_DIR/mem_warming_pattern”.The memory fragmentation pattern of a previous OpenSIPS run. Used at startup, if mem_warming is enabled.

mem_warming_pattern_file = “/var/tmp/my_memory_pattern”

3.51 memdump | mem_dump – Log level to print memory status information (runtime and shutdown). Default: memdump=L_DBG (4)


3.52 memlog | mem_lo- Log level to print memory debug info. It has to be less than the value of ‘log_level’ parameter if you want memory info to be logged. Default: memlog=L_DBG (4)


3.53 mcast_loopback – If set to ‘yes’, multicast datagram are sent over loopback. Default value is ‘no’.


3.54 mcast_ttl – Set the value for multicast ttl. Default value is OS specific (usually 1).


3.55 mhomed – Set the server to try to locate outbound interface on multihomed host. By default is not (0) – it is rather time consuming.


3.56 mpath – Set the module search path. This can be used to simplify the loadmodule parameter

mpath="/usr/local/lib/opensips/modules"<br> loadmodule ""<br> loadmodule ""<br> loadmodule ""<br> loadmodule ""<br> loadmodule ""<br> ...

3.57 open_files_limit – If set and bigger than the current open file limit, OpenSIPS will try to increase its open file limit to this number. Note: OpenSIPS must be started as root to be able to increase a limit past the hard limit (which, for open files, is 1024 on most systems).


3.58 poll_method – The poll method to be used by the I/O internal reactor – by default the best one for the current OS is selected. The available types are: poll, epoll_lt, sigio_rt, select, kqueue, /dev/poll.

Starting with version 2.2, epoll_et is deprecated and if it is used in the script, it will be automatically replaced by epoll_lt.


3.59 port – port the SIP server listens to. The default value for it is 5060.

3.60 reply_to_via – If it is set to 1, any local reply is sent to the address advertised in top most Via of the request. Default value is 0 (off).


3.61 query_buffer_size -If set to a value greater than 1, inserts to DB will not be flushed one by one. Rows to be inserted will be kept in memory until until they gather up to query_buffer_size rows, and only then they will be flushed to the database.


3.62 query_flush_time – If query_buffer_size is set to a value greater than 1, a timer will trigger once every query_flush_time seconds, ensuring that no row will be kept for too long in memory.


3.63 rev_dns – should the SIP server attempt to lookup its own IP address in DNS. If this parameter is set to yes and the IP address is not in DNS a warning is printed on syslog and a “received=” field is added to the via header. Default is no.

3.64 server_header – The body of Server header field generated by OpenSIPS when it sends a request as UAS. It defaults to “OpenSIPS (<version> (<arch>/<os>))”.

server_header=”Server: My Company SIP Proxy”

3.65 server_signature – control “Server” header in any locally generated message. If it is enabled (default=yes) a header is generated as Server: OpenSIPS (0.9.5 (i386/linux))

3.66 shm_hash_split_percentage – Only relevant when the HP_MALLOC compile flag is enabled. It controls how many memory buckets will be optimized. (e.g. setting it to 2% will optimize the first 81 most used buckets as frequency). The default value is 1.

3.67 shm_secondary_hash_size – Only relevant when the HP_MALLOC compile flag is enabled. It represents the optimization factor of a single bucket (e.g. setting it to 4 will cause the optimized buckets to be further split into 4). The default value is 8.

3.68 sip_warning – Can be 0 or 1. If set to 1 (default value is 0) a ‘Warning’ header is added to each reply generated by OpenSIPS. The header contains several details that help troubleshooting using the network traffic dumps.


3.69 tcp_children – Number of children processes to be created for reading from TCP connections. If no value is explicitly set, the same number of TCP children as UDP children (see “children” parameter) will be used.


3.70 tcp_accept_aliases – If enabled, OpenSIPS will enforce RFC 5923 behaviour when detecting an “;alias” Via header field parameter and will reuse any TCP (or TLS, WS, WSS) connection opened for such SIP requests (source IP + Via port + proto) when sending other SIP requests backwards, towards the same (source IP + Via port + proto) pair. Default value 0 (disabled).

3.71 tcp_listen_backlog – maximum length for the queue of pending connections for the TCP listeners. Default configured value is 10.

3.72 tcp_connect_timeout – Time in milliseconds before an ongoing blocking attempt to connect will be aborted. Default value is 100ms.

tcp_connect_timeout = 5

3.73 tcp_connection_lifetime – Lifetime in seconds for TCP sessions. Default value is defined in tcp_conn.h: define DEFAULT_TCP_CONNECTION_LIFETIME 120.

tcp_connection_lifetime = 3600

3.74 tcp_max_connections – maximum number of tcp connections. Default is defined in tcp_conn.h: define DEFAULT_TCP_MAX_CONNECTIONS 2048

tcp_max_connections = 4096

3.75 tcp_max_msg_time – maximum number of seconds that a SIP message is expected to arrive via TCP. Default value is 4

tcp_max_msg_time = 8

3.76 tcp_no_new_conn_bflag -A branch flag to be used as marker to instruct OpenSIPS not to attempt to open a new TCP connection when delivering a request, but only to reuse an existing one (if available). If no existing conn, a generic send error will be returned.

This is intended to be used in NAT scenarios, where makes no sense to open a TCP connection towards a destination behind a NAT (like TCP connection created during registration was lost, so there is no way to contact the device until it re-REGISTER). Also this can be used to detect when a NATed registered user lost his TCP connection, so that opensips can disable his registration as useless.

 tcp_no_new_conn_bflag = TCP_NO_CONNECT<br> ...<br> route {<br> ...<br> if (isflagset(DST_NATED) &amp;&amp; $proto == "TCP")<br>     setbflag(TCP_NO_CONNECT);<br>     ...<br>     t_relay("0x02"); // no auto error reply<br>     $var(retcode) = $rc;<br>     if ($var(retcode) == -6) {<br>         xlog("unable to send request to destination");<br>         send_reply("404", "Not Found");<br>         exit;<br>     } else if ($var(retcode) &lt; 0) {<br>         sl_reply_error();<br>         exit;<br>     }<br> } 

3.77 tcp_threshold – A number representing the maximum number of microseconds sending of a TCP request is expected to last. Anything above the set number will trigger a warning message to the logging facility. Default value is 0 ( logging disabled ).

tcp_threshold = 60000

3.78 tcp_keepalive – Enable or disable TCP keepalive (OS level). Enabled by default.

tcp_keepalive = 1

3.79 tcp_keepcount -Number of keepalives to send before closing the connection (Linux only).

Default value: 0 (not set). Setting tcp_keepcount to any value will enable tcp_keepalive.

tcp_keepcount = 5

3.80 tcp_keepidle – Amount of time before OpenSIPS will start to send keepalives if the connection is idle (Linux only).
Default value: 0 (not set)

tcp_keepidle = 30

3.81 tcp_keepinterval – Interval between keepalive probes, if the previous one failed (Linux only).Default value: 0 (not set). Setting tcp_keepinterval to any value will enable tcp_keepalive.

tcp_keepinterval = 10

3.82 tls_ca_list

3.83 tls_certificate

3.84 tls_ciphers_list

3.85 tls_domain

3.86 tls_handshake_timeout

3.87 tls_log

3.88 tls_method

3.89 tls_port_no

3.90 tls_private_key

3.91 tls_require_certificate

3.92 tls_send_timeout

3.93 tls_verify

3.94 tos – The TOS (Type Of Service) to be used for the sent IP packages (both TCP and UDP).


3.96 user_agent_header – The body of User-Agent header field generated by OpenSIPS when it sends a request as UAC. It defaults to “OpenSIPS (<version> (<arch>/<os>))”.

user_agent_header=”User-Agent: My Company SIP Proxy”

3.97 wdir – working directory used by OpenSIPS at runtime.


3.98 xlog_buf_size – Default value: 4096

Size of the buffer used to print a single line on the chosen logging facility of OpenSIPS. If the buffer is too small, an overflow error will be printed, and the concerned line will be skipped.

xlog_buf_size = 8388608 #given in bytes

3.99 xlog_force_color

xlog_force_color = true //Default value: false

3.100 xlog_default_level -Default value for the logging level of the xlog core function, when the log_level parameter is omitted.

xlog_default_level = 2 #L_NOTICE // Default value: -1


OpenSIPS routing logic uses several types of routes. Each type of route is triggered by a certain event and allows you to process a certain type of message (request or reply).

  • route
    SIP requests routing. The main ‘route’ block identified by ‘route{…}’ or ‘route[0]{…}’ is executed for each SIP request.
    To send a reply or forward the request, explicit actions must be called inside the route block. in example below which sends 200 ok reply for each options request.
route {
if(is_method("OPTIONS")) {
sl_send_reply("200", "ok");
route[1] {
  • branch_route
    Handles different branches of a SIP request. if the branch is not dropped the branch will be automatically sent out. It is executed only by TM module after it was armed via t_on_branch(“branch_route_index”).
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");

or lookup location and discard branches where uri matches ip by using drop()

route {
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
branch_route[op3] {
if(uri=~"1\.2\.3\.4") {
  • failure_route
    Failed transaction routing block. It contains a set of actions to be taken each transaction that received only negative replies (>=300) for all branches which completes the transaction. The ‘failure_route’ is executed only by TM module after it was armed via t_on_failure(“failure_route_index”).
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");

failure_route[MANAGE_FAILURE] {
if (t_is_canceled()) {

or on failure relay to voice mail

route {
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
failure_route[op1] {
if(is_method("INVITE")) {
  • onreply_route
    Reply routing block. It can be stateful (if bound to a transaction) or stateless (if global reply route).
    If the reply is not dropped (only provisional replies can be), it will be injected and processed by the transaction engine. There are three types of onreply routes:

global – catches all replies and uses simple definition ‘onreply_route {…}’ or ‘onreply_route[0] {…}’.
Exmaple for “global” reply route set the whole transaction

route {
seturi("");  first branch
append_branch("");  second branch

onreply_route {
xlog("OpenSIPS received a reply from $si\n");

onreply_route[global] {
if (t_check_status("1[0-9][0-9]")) {
log("provisional reply received\n");
if (t_check_status("183"))

per request/transaction – it catches all received replies belonging to a certain transaction and uses “t_on_reply()” at request time, in REQUEST ROUTE – named ‘onreply_route[N] {…}’.

per branch – it catches only the replies that belong to a certain branch from a transaction via “t_on_reply()” ) at request time, but in BRANCH ROUTE, when a certain outgoing branch is processed – named ‘onreply_route[N] {…}’.
Certain ‘onreply_route’ blocks can be executed by TM module for special replies. For this, the ‘onreply_route’ must be armed for the SIP requests whose replies should be processed within it, via t_on_reply(“onreply_route_index”).

Exmaple of reply route set for this branch only

branch_route[1] {
if ($rU=="alice")

onreply_route[alice] {
xlog("received reply on the branch from alice\n");
  • error_route

executed automatically on meeting and error such as parsing error in SIP request processing, script assert failure. Performs error handling . The Default action is to discard request. In error_route, the following pseudo-variables are available to get access to error details:

$(err.class) - the class of error (now is '1' for parsing errors)
$(err.level) - severity level for the error
$( - text describing the error
$(err.rcode) - recommended reply code
$(err.rreason) - recommended reply reason phrase
error_route {
xlog("--- error route class=$(err.class) level=$(err.level)
info=$( rcode=$(err.rcode) rreason=$(err.rreason) ---\n");
xlog("--- error from [$si:$sp]\n+++++\n$mb\n++++\n");
sl_send_reply("$err.rcode", "$err.rreason");
  • local_route

executed automatically as TM created a new request, internally (no UAC side). This is a route intended to be used for message inspection, accounting and for applying last changes on the message headers. Routing and signaling functions are not allowed.

local_route {
if (is_method("INVITE") && $ru=~"") {
append_hf("P-hint: foreign request\r\n");
if (is_method("BYE") ) {
acc_log_request("internally generated BYE");
  • startup_route
    Executed only once when OpenSIPS is started and before the processing of SIP messages begins. Used in initilization cases cases such as loading some data in the cache.
startup_route {
avp_db_query("select gwlist where ruleid==1",$avp(i:100));
cache_store("local", "rule1", "$avp(i:100)");
  • timer_route
    Route executed periodically at a configured interval of time specified next to the name(in seconds).
timer_route[gw_update, 300] {
avp_db_query("select gwlist where ruleid==1",$avp(i:100));
$shv(i:100) =$avp(i:100);
  • event_route
    execute script code when an event is triggered. If no way to handle the event specified, default will be synchronously.
    Triggered by the event_route module when an event is raised by the OpenSIPS Event Interface such as event raised by the pike module when it decides an ip should be blocked called E_PIKE_BLOCKED or E_SCRIPT_EVENT etc ( checke events interface for more events)
event_route[E_PIKE_BLOCKED] {
xlog("The E_PIKE_BLOCKED event was raised\n");
event_route[E_PIKE_BLOCKED, async] {
xlog("The E_PIKE_BLOCKED event was raised\n");

Ref :

Lua Scripts for kamailio Routing

Kamailio uses a native scripting laguage for its configuration file kamailio.cfg . This components of this file are :

  • global parameters
  • loading modules
  • module parameters
  • routing blocks like request_route {…}, reply_route {…}, branch_route {…} etc

These parameters including initialization event routes , are interpeted and loaded at kamailio startup.

We know that restart of sip server hinder all ongoing traffic and slows development of routing logic.
Due to limitation of customizatiosn with native language and mostly due to the fact that interpreter precompiles kamailio.cfg at startup preventing routing script to reload without restart , other programming languages were used such as Kamailio Embedded Interface (KEMI) framework.

Post v5 of kamailio , the interpreters of these languages were integrated with kamailio and feature rich SIP routing logic could be written with them for runtime execution. The routing blocks are in form of functions written in a KEMI ( Kamaialio EMbedded Interface) supported scripting language such as Lua as discussed in this article. Other components are still initialised by kamailio.cfg at starup. Apart from above mentioned advantages of programming languages , another plus point is that it enables test-cases , debug functionality without having to restart the server for code update.

KEMI supported programming languages:

  • JavaScript (app_jsdt)
  • Lua (app_lua)
  • Python (app_python)
  • Python3 (app_python3)
  • Squirrel (app_sqlang)

Kamailio has other modules that allow inline execution of scripts written in other programming languages, but don’t implement the KEMI yet. Such as
Perl (app_perl)
.Net (C#, etc.)
Java (app_java)

As Kamailio becomes the interpreter for these languages , it executes logic faster at runtime . KEMI also extends the modules with extension to kamailio c functions

Lua KEMI Interpreter

Lua interpreter is linked from liblua library in app_lua module.

loadmodule ""
//script path
modparam("app_lua", "load", "/path/to/script.lua")
//specifying engine
cfgengine "lua"

Predefined functions in app_lua module

ksr_request_route() : executed by Kamailio core every time a SIP request is received, equivalent of request_route {} from kamailio.cfg

ksr_reply_route() : executed by Kamailio core every time a SIP Response (reply) is received, equivalent of reply_route {} from kamailio.cfg

ksr_onsend_route() : executed when a SIP request (and optionally for a response) is sent out, equivalent of onsend_route {}

branch route callback : name of the Lua function to be executed instead of a branch route has to be provided as parameter to…)

onreply route callback : name of the Lua function to be executed instead of an onreply route has to be provided as parameter to…)

failure route callback : name of the Lua function to be executed instead of a failure route has to be provided as parameter to…)

branch failure route callback : name of the Lua function to be executed instead of an event route for branch failure has to be provided as parameter to…)

event route callback : name of the Lua function to be exectued instead of module specific event_route blocks is provided via event_callback parameter of that module

KSR is the new dynamic object exporting Kamailio functions. sr is the old static object exporting Kamailio functions

route.lua for routing logic

function ksr_request_route()"===== request - from kamailio lua script\n");
    if KSR.maxfwd.process_maxfwd(10) < 0 then, "Too Many Hops");
    //, "OK Lua");
    KSR.pv.sets("$du", "sip:")"ksr_branch_route_one");"ksr_onreply_route_one");"ksr_failure_route_one");
    if < 0 then, "Server error")

function ksr_reply_route()"===== response - from kamailio lua script\n");

function ksr_branch_route_one()"===== branch route - from kamailio lua script\n");

function ksr_onreply_route_one()"===== onreply route - from kamailio lua script\n");

function ksr_failure_route_one()"===== failure route - from kamailio lua script\n");

Core Kemi functions

KSR.add_local_rport() : Set the internal flag to add rport parameter to local generated Via header.

KSR.add_tcp_alias() : Adds a tcp port alias for the current connection (if tcp). Can help in firewall or nat traversal

KSR.add_tcp_alias_via() : Adds the port from the message via as an alias to TCP connection.

void KSR.dbg(…) : debug log

KSR.dbg("debug log message from embedded interpreter\n");

void KSR.err(…) : error logging

KSR.err("error log message from embedded interpreter\n");

void…) : info log"info log message from embedded interpreter\n");

KSR.force_rport() : Add rport parameter to the top Via of the incoming request and sent the SIP response to source port.

KSR.is_method() : Return true if the value of the parameter matches the method type of the SIP message.

if(KSR.is_method("INVITE")) {

KSR.is_method_in() ; Return true if SIP method of the currently processed message is matching one of the corresponding characters given as parameter. Matching the method is done based on corresponding characters:

if KSR.is_method_in("IABC") then
  -- the method is INVITE, ACK, BYE or CANCEL

KSR.is_INVITE() : Return true if the method type of the SIP message is INVITE.

KSR.is_ACK() : true if the method type is ACK.

KSR.is_BYE() : true if the method type is BYE.

KSR.is_CANCEL() : true if CANCEL.


KSR.is_MESSAGE() : true if SIP message is MESSAGE.

KSR.is_SUBSCRIBE() : true if SIP message is SUBSCRIBE.

KSR.is_PUBLISH() : true if PUBLISH.

KSR.is_NOTIFY() : true if NOTIFY.

KSR.is_OPTIONS() : true if OPTIONS.

KSR.is_INFO() : true if INFO.

KSR.is_UPDATE() : true if UPDATE.

KSR.is_PRACK() : true if PRACK.

KSR.is_myself(…) : Return true of the URI address provided as parameter matches a local socket (IP) or local domain.

if KSR.is_myself("sip:") then

KSR.is_myself_furi() : Return true if the URI in From header matches a local socket (IP) or local domain.

KSR.is_myself_ruri() : Return true if the R-URI matches a local socket (IP) or local domain.

KSR.is_myself_turi() : Return true if the URI in To header matches a local socket (IP) or local domain.

KSR.is_myself_suri() : true if the URI built from source IP, source port and protocol matches a local socket (IP).

KSR.is_myself_suri() : true if the source IP matches a local socket (IP).

void KSR.log(…) : Write a log message specifying the level value. The level parameter can be: “dbg” , “info” , “warn” , “crit” , “err”

KSR.setflag(…) : Set the SIP message/transaction flag ( int from 0 to 31 ) at the index provided by the parameter.

KSR.resetflag(…) : Reset the SIP message/transaction flag ( int from 0 to 31 ) at the index provided by the parameter.

KSR.isflagset(…) :Return true if the message/transaction flag at the index provided by the parameter is set (the bit has value 1).

KSR.setbflag(…) : Set the branch flag(0-31) at the index provided by the parameter.

KSR.resetbflag(…) : Reset the branch flag(0-31) at the index provided by the parameter.

KSR.isbflagset(…) : Return true if the branch flag at the index provided by the parameter is set (the bit has value 1).

KSR.setbiflag(…) : Set the flag at the index provided by the first parameter to the branch number specified by the second parameter. The flag parameter has to be a number from 0 to 31. The branch parameter should be between 0 and 12 (a matter of max_branches global parameter).

KSR.resetbiflag(…) : Reset a branch flag by position and branch index.

KSR.isbiflagset(…) : Test if a branch flag is set by position and branch index.

KSR.setsflag(…) : Set a script flag.

KSR.resetsflag(…) : Reset a script flag.

KSR.issflagset(…) : Test if a script flag is set.

KSR.seturi(…) : Set the request URI (R-URI).








KSR.resetdsturi(…) : Reset the destination URI (aka: outbound proxy address, dst_uri, $du).

KSR.isdsturiset(…) : Test if destination URI is set.

KSR.force_rport(…) : Set the flag for “rport” handling (send the reply based on source address instead of Via header).

KSR.set_drop(…) : Set the DROP flag, so at the end of KEMI script execution, the SIP request branch or the SIP response is not forwarded.

KSR.set_advertised_address() : Set the address (host or ip) to be advertised in Via header.

KSR.set_advertised_port() : Set the port (in string format) to be advertised in Via header.

KSR.set_forward_close(…) : Set the flag to close the connection after forwarding the message.

KSR.set_forward_no_connect(…) : Set the flag to not open a connection if the connection to the target does not exist when attempting to forward a message.

KSR.set_reply_close(…) : Set the flag to close the connection after sending a response.

KSR.set_reply_no_connect(…) : Set the flag to not open a connection if the connection for sending the response does not exist.

KSR.forward(…) : Forward the SIP request in stateless mode to the address set in destination URI ($du), or, if this is not set, to the address in request URI ($ru).

KSR.forward_uri(…) : Forward the SIP request in stateless mode to the address provided in the SIP URI parameter.


KSR.hdr.append(…) : Append header to current SIP message (request or reply).

KSR.hdr.append("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n");

KSR.hdr.append_after(…) : Append header to current SIP message (request or reply). It will be added after the first header matching the name hdrname.

KSR.hdr.append_after("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n", "Call-Id");

KSR.hdr.insert(…) : Insert header to current SIP message (request or reply). It will be added before the first header.

KSR.hdr.insert("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n");

KSR.hdr.insert_before(…) : Insert header to current SIP message (request or reply). It will be added before the header matching the name hdrname.

KSR.hdr.insert_before("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n", "Call-Id");

KSR.hdr.remove(…) : Remove all the headers with the name hdrval.


KSR.hdr.is_present(…) : Return greater than 0 if a header with the name hdrval exists and less than 0 if there is no such header.

if(KSR.hdr.is_present("X-My-Hdr") > 0) {

KSR.hdr.append_to_reply(…) : Add a header to the SIP response to be generated by Kamailio for the current SIP request.

KSR.hdr.append_to_reply("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n");

PV And Special KEMI Functions

PV And Special KEMI Functions

KSR.pv submodule provides the functions to get, set and test the values of pseduo-variables.
The pvname that appears in the next sections in the function prototypes has to be a valid pseudo-variable name for Kamailio native configuration file (for example $ru, $var(x), $shv(z), …).

KSR.pv.get(…) : Return the value of pseudo-variable pvname. The returned value can be string or integer.

KSR.dbg("ruri is: " + KSR.pv.get("$ru") + "\n");

KSR.pv.gete(…) : Return the value of pseudo-variable pvname if it is different than $null or the empty string (“”) if the variable is having the $null value.

KSR.dbg("avp is: " + KSR.pv.gete("$avp(x)") + "\n");

KSR.pv.getvn(…) : Return the value of pseudo-variable pvname if it is different than $null or the parameter vn if the variable is having the $null value.

KSR.dbg("avp is: " + KSR.pv.getvn("$avp(x)", 0) + "\n");

KSR.pv.getvs(…) : Return the value of pseudo-variable pvname if it is different than $null or the parameter vs if the variable is having the $null value.

KSR.dbg("avp is: " + KSR.pv.getvs("$avp(x)", "foo") + "\n");

KSR.pv.getw(…) : Return the value of pseudo-variable pvname if it is different than $null or the string <> if the variable is having the $null value. This should be used instead of KSR.pv.get(…) in the scripting languages that throw and error when attempting to print a NULL (or NIL) value.

KSR.dbg("avp is: " + KSR.pv.getw("$avp(x)") + "\n");

KSR.pv.seti(…) : set the value of pseudo-variable pvname to integer value provided by parameter val.

KSR.pv.seti("$var(x)", 10);

KSR.pv.sets(…) : set the value of pseudo-variable pvname to string value provided by parameter val.

KSR.pv.sets("$var(x)", "kamailio");

KSR.pv.unset(…) : Set the value of pseudo-variable pvname to $null.


KSR.pv.is_null(…) : Return true if pseudo-variable pvname is $null.

if(KSR.pv.is_null("$avp(x)")) {

KSR.x.modf(…) : Execute a function (specified by fname) exported by a Kamailio module.

KSR.x.modf("sl_send_reply", "200", "OK");

KSR.x.exit(…) : stop the execution of the SIP routing script.

KSR.x.drop(…) : stop the execution of the SIP routing script and drop routing further the SIP request branch or response.

KEMI Module Functions

Module specific exported KEMI functions.






executing Lua scripts from config file.








asynchronous operations for handling SIP requests











-tbd –

Ref :

Kamailio Security

Security is Critical for a VoIP platform as it is susceptible to hacks , misuse , eavesdropping or just sheer misuse of the system by making robotic flood calls . Kamailio SIP Server provides some key features to meet these challenges which will be discussed in this blog .

Hiding Details

Hiding Details like ip addresses of your VoIP platform is of paramount importance since many headers in SIP reqyest / resposne expose ip address such as Via , contact address , Record-Route and sometimes the Call-ID too

topoh module

Primiarily it does these things
hide the addresses of PSTN gateways
protect your internal network topology
interconnection provider – to keep the details of connected parties secret to the other, to prevent a bypass of its service in the future

modparam("topoh", "mask_key", "YouDoHaveToChangeThisKey")
modparam("topoh", "mask_ip", "")
modparam("topoh", "mask_callid", 1)

topos module

offers topology hiding by stripping the SIP routing headers that show topology details.

Parameters :
storage (str)
db_url (str)
mask_callid (int)
sanity_checks (int)
branch_expire (int)
dialog_expire (int)
clean_interval (int)
event_callback (str)

event route :

loadmodule ""
loadmodule ""

//topos params 
modparam("topos", "storage", "redis")
//branch_expire is 10 min
modparam("topos", "branch_expire", 10800)
// dialog_expire is 1 day
modparam("topos", "dialog_expire", 10800)
modparam("topos", "sanity_checks", 1)


To save from the automatic port scans that attackers carry out to hack into the system use the script below

:CHECK_TCP - [0:0]
:ICMP - [0:0]
:PRIVATE - [0:0]
:PSD - [0:0]
:SERVICES - [0:0]
-A INPUT -i lo -j ACCEPT 
-A INPUT -i eth0 -p ipv6 -j ACCEPT 
-A OUTPUT -o lo -j ACCEPT 
-A CHECK_TCP -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,ACK -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags FIN,ACK FIN -m state --state INVALID,NEW,RELATED -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags PSH,ACK PSH -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags ACK,URG URG -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-option 64 -j DROP 
-A CHECK_TCP -p tcp -m tcp --tcp-option 128 -j DROP 
-A ICMP -p icmp -m icmp --icmp-type 11/1 -m limit --limit 5/sec -m state --state NEW -j ACCEPT 
-A ICMP -p icmp -m icmp --icmp-type 11/0 -m limit --limit 5/sec -m state --state NEW -j ACCEPT 
-A ICMP -p icmp -m icmp --icmp-type 3 -m limit --limit 10/sec -m state --state NEW -j ACCEPT 
-A ICMP -p icmp -m icmp --icmp-type 8 -m limit --limit 10/sec --limit-burst 10 -m state --state NEW -j ACCEPT 
-A ICMP -p icmp -j DROP 
-A PSD -p tcp -m statistic --mode random --probability 0.050000 -j REJECT --reject-with icmp-port-unreachable 
-A PSD -p tcp -m statistic --mode random --probability 0.050000 -j TARPIT  --reset 
-A PSD -p tcp -m statistic --mode random --probability 0.500000 -j TARPIT  --tarpit 
-A PSD -p udp -m statistic --mode random --probability 0.050000 -j REJECT --reject-with icmp-port-unreachable 
-A PSD -m statistic --mode random --probability 0.050000 -j REJECT --reject-with icmp-host-unreachable  
-A SERVICES -p icmp -m state --state INVALID -j DROP 
-A SERVICES -p icmp -j ICMP 
-A SERVICES -p udp -m udp --dport 123 -m state --state NEW -j ACCEPT 
-A SERVICES -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT 
-A SERVICES -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT 
-A SERVICES -p tcp -m udp -m multiport --dports 5060 -m state --state NEW -j ACCEPT 
-A SERVICES -p tcp -m udp -m multiport --dports 5061 -m state --state NEW -j ACCEPT 
-A SERVICES -i eth0 -j PSD 

Update/Remove Server and User Agent Headers

Rewrite server header to save the exact version of server from hackers

server_header="Server: Simple Server"

or completely rmemove it from traces



user_agent_header="User-Agent: My SIP Server"

Remove Server warnings from traces and log file

Warnings expose the vulnerabilities of system and it is best to remove them in production enviornment

user_agent_header="User-Agent: My SIP Server"

Anti Flood

During Auth or logging there is a fair chance of leaking credentials or the fact that users opt for weak password themselves compromising the system via bruteforcing username/password . Or attacker may be bruteforcing prefixes to understand config and routing logic
Random unnecessary flood of SIP requests can consume CPU and make it slow or unavailable for others as Denial of Service . These situations can be made less daunting via pike module

pike modules

tracks the number of SIP messages per source IP address, per period.

loadmodule ""

// pike params 
modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 20)
modparam("pike", "remove_latency", 4)

//routing logic inclusion
route {
  if (!pike_check_req()) {
    xlog("L_ALERT","ALERT: pike block $rm from $fu (IP:$si:$sp)\n");


can syslog files for specific messages based on regular expressions and act upon matching by banning IP addresses.

Traffic Monitoring and Detection

Secfilter module

offer an additional layer of security over our communications. It can perform

  • Blacklisting user agents, IP addresses, countries, domains and users.
  • Whitelisting user agents, IP addresses, countries, domains and users.
  • Blacklist of destinations where the called number is not allowed.
  • SQL injection attacks prevention.

Digest Authetication

Digest is a cryptographic function based on symmetrical encryption.
Read more

Sip server Brekeke

We used Brekeke SIP server to run our SIP applications . Although there are newer versions of Brekeke SIP server out now . More awesome than before , we prefer using the old one for the sake of not messing with legacy SIP applications . The official site for brekeke is – .

A general architecture of Brekeke SIP server is . brekeke

Here are the steps of installing and configuring a Brekeke SIP server .

Step 1: Download the Server form and run the setup file .





brekek2 brekek3 brekek6

brekeke4 brekeke5 brekeke7  brekeke9

Step 2: It is always good to give a look to README file . brekeke11

Step 3: Run the local implementation of SIP server at localhost or at port 8080brekeke12

Step 4: Important is to get the license which will help us activate the SIP server . One can obtain a free license from

Step 5 : Once the license is activates , we can goto the console screen after loggin with default username and password sa . brekeke13

Step 6 : Once we are at console , we could add/ delete / modify parameters like port , start/shutdown status etc . brekeke14 brekeke14_001Step 7 : Once the server is all setup , just add the IP and port of SIP server to SIP clients server filed . Now all the SIP request and response will be catered by this SIP Server

Kamailio Modules

Post has been edited after publishing with updated content and Kamailio modules .

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.

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.

Usrloc Module

keeps a user location table and provides access to the table for other modules


  • 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.lookup table AOR
ul.rm table AOR
ul.rm_contact table AOR contact




ul_insert_urecord(domain, aor, rec)
ul_delete_urecord(domain, aor)
ul_delete_urecord_by_ruid(domain, ruid)
ul_get_urecord(domain, aor)
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)


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])
registered(domain [, uri [, match_option [, match_action]]])
unregister(domain, uri[, ruid])
reg_fetch_contacts(domain, uri, profile)

Event Routes :


Statistics :


Ref :


Keep track of current dialogs also provides API support . It can be loaded and used like given below .

loadmodule ""

# ---- dialog params ----
modparam("dialog", "enable_stats", 1)
modparam("dialog", "dlg_flag", 4)
modparam("dialog", "event_callback", "ksr_dialog_event")

Parameters :

  • enable_stats (integer)
  • hash_size (integer)
  • rr_param (string)
  • dlg_flag (integer)
  • timeout_avp (string)
  • default_timeout (integer)
  • early_timeout (integer)
  • noack_timeout (integer)
  • end_timeout (integer)
  • dlg_extra_hdrs (string)
  • dlg_match_mode (integer)
  • detect_spirals (integer)
  • db_url (string)
  • db_mode (integer)
  • db_update_period (integer)
  • db_fetch_rows (integer)
  • db_skip_load (integer)
  • table_name (string)
  • call_id_column (string)
  • from_uri_column (string)
  • 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 (string)
  • vars_h_id_column (string)
  • vars_h_entry_column (string)
  • vars_key_column (string)
  • 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 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)"===== 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 then
logger.log("err", "Failed")
logger.log("info", "successfully posted")
  • h_id_start (int)
  • h_id_step (int)

Functions :

dlg_refer(side, address)
dlg_bridge(from, to, op)
dlg_get(callid, ftag, ttag)
dlg_set_timeout(timeout [, h_entry, h_id])
dlg_set_timeout_by_profile(profile, [value], timeout)
dlg_remote_profile(cmd, profile, value, uid, expires)

Statistics :


RPC Commands :


Exported Variables :


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 .

RTP Proxy

Used to proxy the media stream . Example : Sippy RTPproxy , ngcp-rtpproxy-ng . Multiple RTP proxies can be used for load distribution and balancing . RTP proxy can also operated in bridging mode to setup bridge signalling between multiple network interfaces. It does not support transcoding.

Parameters :

  • rtpproxy_sock – binds a ip and port for rtp proxy
    modparam(“rtpproxy”, “rtpproxy_sock”, “udp:localhost:12221”)
  • 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 attachemnt 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)


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 {

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


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")) { 
if (is_audio_on_hold()) {
rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", "-1");
} else {

rtpproxy_stream2uas(prompt_name, count)

rtpproxy_stop_stream2uac()- Stop streaming of announcement/prompt/MOH


Exported Pseudo Variables

RPC Commands


RTP Engine

media streams to be proxied via an RTP proxy.

loadmodule ""

# ----- rtpengine params -----
modparam("rtpengine", "db_url", DBURL)
modparam("rtpengine", "table_name" , "rtpengine")
modparam("rtpengine", "rtpengine_allow_op", 1)
modparam("rtpengine", "queried_nodes_limit", 4)
modparam("rtpengine", "rtpengine_retr", 2)
modparam("rtpengine", "rtp_inst_pvar", "$avp(RTP_INSTANCE)")
modparam("rtpengine", "setid_default", 1)
modparam("rtpengine", "mos_min_pv", "$avp(mos_min)")
modparam("rtpengine", "mos_min_at_pv", "$avp(mos_min_at)")
modparam("rtpengine", "mos_min_packetloss_pv", "$avp(mos_min_packetloss)")
modparam("rtpengine", "mos_min_jitter_pv", "$avp(mos_min_jitter)")
modparam("rtpengine", "mos_min_roundtrip_pv", "$avp(mos_min_roundtrip)")
modparam("rtpengine", "rtpengine_tout_ms", 300)

source :


  • rtpengine_sock (string)
  • rtpengine_disable_tout (integer)
  • rtpengine_tout_ms (integer)
  • rtpengine_allow_op (integer)
  • queried_nodes_limit (integer)
  • rtpengine_retr (integer)
  • extra_id_pv (string)
  • setid_avp (string)
  • force_send_interface (string)
  • read_sdp_pv (string)
  • write_sdp_pv (string)
  • rtp_inst_pvar (string)
  • hash_table_size (integer)
  • hash_table_tout (integer)
  • db_url (string)
  • table_name (string)
  • setid_col (string)
  • url_col (string)
  • weight_col (string)
  • disabled_col (string)
  • setid_default (integer)
  • mos_min_pv (string)
  • mos_min_at_pv (string)
  • mos_min_packetloss_pv (string)
  • mos_min_jitter_pv (string)
  • mos_min_roundtrip_pv (string)
  • mos_max_pv (string)
  • mos_max_at_pv (string)
  • mos_max_packetloss_pv (string)
  • mos_max_jitter_pv (string)
  • mos_max_roundtrip_pv (string)
  • mos_average_pv (string)
  • mos_average_packetloss_pv (string)
  • mos_average_jitter_pv (string)
  • mos_average_roundtrip_pv (string)
  • mos_average_samples_pv (string)
  • mos_A_label_pv (string)
  • mos_min_A_pv (string)
  • mos_min_at_A_pv (string)
  • mos_min_packetloss_A_pv (string)
  • mos_min_jitter_A_pv (string)
  • mos_min_roundtrip_A_pv (string)
  • mos_max_A_pv (string)
  • mos_max_at_A_pv (string)
  • mos_max_packetloss_A_pv (string)
  • mos_max_jitter_A_pv (string)
  • mos_max_roundtrip_A_pv (string)
  • mos_average_A_pv (string)
  • mos_average_packetloss_A_pv (string)
  • mos_average_jitter_A_pv (string)
  • mos_average_roundtrip_A_pv (string)
  • mos_average_samples_A_pv (string)
  • mos_B_label_pv (string)
  • mos_min_B_pv (string)
  • mos_min_at_B_pv (string)
  • mos_min_packetloss_B_pv (string)
  • mos_min_jitter_B_pv (string)
  • mos_min_roundtrip_B_pv (string)
  • mos_max_B_pv (string)
  • mos_max_at_B_pv (string)
  • mos_max_packetloss_B_pv (string)
  • mos_max_jitter_B_pv (string)
  • mos_max_roundtrip_B_pv (string)
  • mos_average_B_pv (string)
  • mos_average_packetloss_B_pv (string)
  • mos_average_jitter_B_pv (string)
  • mos_average_roundtrip_B_pv (string)
  • mos_average_samples_B_pv (string)


set_rtpengine_set(setid[, setid])
Exported Pseudo Variables

RPC Commands

rtpengine.enable proxy_url/all 0/1 proxy_url/all proxy_url/all

This set deals with HTTP and Websocket adapters to handle web pone based ( such as webRTC) calls on kamailio


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:


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
Example :
modparam(“xhttp”, “event_callback”, “ksr_xhttp_event”)
and the event callback function implemented in Lua
function ksr_xhttp_event(evname)“===== xhttp module triggered event: ” .. evname .. “\n”);
return 1;


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

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 – [$si:$sp]</body></html>”);

Websocket Module

provide 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).


Telephony Solutions with Kamailio

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 .

IMS extensions for VoLTE; ENUM; DID and least cost routing; load balancing; routing fail-over; Json and XMLRPC control interface, SNMP monitoring.


  • SIP (RFC3261) support

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 an Redirect , Dispatcher or simply a SIP over websocket server.

  • Kamailio is Customisable to suit business requirement and scale .

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.

Due to its 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.

  • Call routing and control functionality 

Offers stateless and transactional stateful SIP Proxy processing ( suited for inbound gateways ) and serial and parallel forking.

Also NAT traversal support for SIP and RTP traffic ( suited to be WebRTC server )

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
  • IP and DNS

    • support for SRV and NAPTR DNS lookups
    • SRV DNS failover
    • DNSsec support
    • ENUM support
    • internal DNS caching system – avoid DNS blocking
    • IP level Blacklists
    • multi-homed and multi-domain support
    • 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

  • Multiple Database Backends

(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.)

  • IMS

    • diameter support and authentication
    • charging, QOS, ISC
  • Miscellaneous

    • CPL – Call Processing Language (RFC3880)
    • Internal generic caching system
    • Memcached connector
    • Redis NoSQL database connector
    • CLI – kamctl and sercmd
    • Web Management Interface: Siremis
    • SIP-T and SIP-I
    • music on hold queue
    • message body compression/decompression (gzip-deflate)
  • Extensive documentation for both administrators and developers


  • Kamailio can run on embedded systems, with limited resources – the performances can be up to hundreds of call setups per second
  • used as load balancer in stateless mode, Kamailio can handle over 5000 call setups per second
  • on systems with 4GB memory, Kamailio can serve a population over 300 000 online subscribers
  • system can easily scale by adding more Kamailio servers
  • Kamailio can be used in geographic distributed VoIP platforms
  • Kamailio least-cost-routing scales up to millions of routing rules
  • straightforward failover and redundancy

Start Kamalio

service kamailo start


tail -f /var/log/kamailio

To Check if Kamailio instance is running

>ps -ax | grep “kamailio”

57411 ?        S      0:01 /usr/sbin/kamailio -f /etc/kamailio/kamailio.cfg -P /var/run/kamailio/ -m 4096 -M 128 -u root -g root

Installation and Configuration

Installing kammlio from git repo

clone kamailio from their github

goto desired branch

The contents of clonned folder are

COPYING ChangeLog INSTALL ISSUES Makefile README doc etc misc pkg test utils

run ‘make cfg’ which compiles using gcc abd created ‘src’ folder with contents

make cfg

Makefile Makefile.defs Makefile.groups Makefile.modules Makefile.rules Makefile.sources Makefile.utils core main.c modules.lst Makefile.cfg Makefile.dirs Makefile.libs Makefile.radius Makefile.shared Makefile.targets config.mak lib modules

Edit modules.lst to enable db_mysql and dialplan module

vim src/modules.lst

//the list of extra modules to compile

include_modules= db_mysql

Use ‘make’ command followed by make all . Make sure to have gcc bison and flex installed

make cfg

make all

Alternativey on debian system , use readymade measures like

apt install mysql-server

apt install kamailio kamailio-mysql-modules

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’

Database access
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.


chrooted directory


database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE by default none is loaded


Run kamdbctl to create users and database now

kamdbctl create

the databa created is name kamailio and its tables are

  • +———————+
  • | Tables_in_kamailio  |
  • +———————+
  • | acc                 |
  • | acc_cdrs            |
  • | active_watchers     |
  • | address             |
  • | aliases             |
  • | carrier_name        |
  • | carrierfailureroute |
  • | carrierroute        |
  • | cpl                 |
  • | dbaliases           |
  • | dialog              |
  • | dialog_vars         |
  • | dialplan            |
  • | dispatcher          |
  • | domain              |
  • | domain_attrs        |
  • | domain_name         |
  • | domainpolicy        |
  • | globalblacklist     |
  • | grp                 |
  • | htable              |
  • | imc_members         |
  • | imc_rooms           |
  • | lcr_gw              |
  • | lcr_rule            |
  • | lcr_rule_target     |
  • | location            |
  • | location_attrs      |
  • | missed_calls        |
  • | mohqcalls           |
  • | mohqueues           |
  • | mtree               |
  • | mtrees              |
  • | pdt                 |
  • | pl_pipes            |
  • | presentity          |
  • | pua                 |
  • | purplemap           |
  • | re_grp              |
  • | rls_presentity      |
  • | rls_watchers        |
  • | rtpproxy            |
  • | sca_subscriptions   |
  • | silo                |
  • | sip_trace           |
  • | speed_dial          |
  • | subscriber          |
  • | trusted             |
  • | uacreg              |
  • | uid_credentials     |
  • | uid_domain          |
  • | uid_domain_attrs    |
  • | uid_global_attrs    |
  • | uid_uri             |
  • | uid_uri_attrs       |
  • | uid_user_attrs      |
  • | uri                 |
  • | userblacklist       |
  • | usr_preferences     |
  • | version             |
  • | watchers            |
  • | xcap                |
  • +———————+


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
## chrooted directory
# $CHROOT_DIR="/path/to/chrooted/directory"
# by default none is loaded

# If you want to setup a database with kamdbctl, you must at least specify this parameter.

## database host
# DBHOST=localhost
## database host
# 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)

database super user (for ORACLE this is ‘scheme-creator’ user)

## 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)
## user name column
# USERCOL="username"
# SQL definitions

# If you change this definitions here, then you must change them
# in db/schema/entities.xml too.
# 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.

# If to install presence related tables.
# If to install uid modules related tables.

 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 acc lcr domain group permissions registrar usrloc msilo
alias_db uri_db speeddial avpops auth_db pdt dialog dispatcher

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 RPCFIFO

## path to FIFO file for engine RPCFIFO
# RPCFIFOPATH="/var/run/kamailio/kamailio_rpc_fifo"

## check ACL names; default on (1); off (0)

## 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)


## verbose - debug purposes - default '0'

## do (1) or don't (0) store plaintext passwords
## in the subscriber table - default '1'


Kamailio START Options

PID file path – default is: /var/run/kamailio/

# PID_FILE=/var/run/kamailio/

Extra start options – default is: not set

# example: start Kamailio with 64MB share memory: STARTOPTIONS="-m 64"


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 123
mysql: [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
  • 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)
  • presence services

Kamailio (OpenSER) SIP Server v4.3- default configuration script

Several features can be enabled using ‘#!define WITH_FEATURE’ directives:

To run in debug mode: define WITH_DEBUG

To enable mysql: define WITH_MYSQL

To enable authentication execute: enable mysql and  define WITH_AUTH

To enable IP authentication execute: enable mysql ,  enable authentication ,  define WITH_IPAUTH and  add IP addresses with group id ‘1’ to ‘address’ table

To enable persistent user location execute:

enable mysql


To enable presence server execute:

enable mysql


To enable nat traversal execute:

define WITH_NAT

Install RTPProxy:

start RTPProxy:

rtpproxy -l your_public_ip -s udp:localhost:7722

option for NAT SIP OPTIONS keepalives: WITH_NATSIPPING

To enable PSTN gateway routing execute:

define WITH_PSTN

set the value of pstn.gw_ip

check route[PSTN] for regexp routing condition

To enable database aliases lookup execute:

enable mysql


To enable speed dial lookup execute:

enable mysql


To enable multi-domain support execute:

enable mysql


To enable TLS support execute:

adjust CFGDIR/tls.cfg as needed

define WITH_TLS

To enable XMLRPC support execute:


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)


To block 3XX redirect replies execute:


To enable VoiceMail routing execute:


set the value of voicemail.srv_ip

adjust the value of voicemail.srv_port

To enhance accounting execute:

enable mysql


add following columns to database


define WITH_AUTH





ALTER TABLE acc ADD COLUMN src_ip 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_domain VARCHAR(128) NOT NULL DEFAULT '';


Include Local Config If Exists

import_file “kamailio-local.cfg”

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.

 #!ifndef DBURL 
 #!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" 
  #!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" 
# !endif

 #!ifdef WITH_MULTIDOMAIN# - the value for 'use_domain' paramete
 #!define MULTIDOMAIN 1
 #!define MULTIDOMAIN 0

 # FLT_ - per transaction (message) flags 
 # FLB_ - per branch flags
 #!define FLT_ACC 1
 #!define FLT_ACCMISSED 2
 #!define FLT_ACCFAILED 3
 #!define FLT_NATS 5
 #!define FLB_NATB 6

 !substdef "!MY_IP_ADDR!!g"
 #!substdef "!MY_DOMAIN!!g" 
 #!substdef "!MY_WS_PORT!8080!g"
 #!substdef "!MY_WSS_PORT!4443!g"
 #!substdef "!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g"
 #!substdef "!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g"</pre>
 #!ifdef WITH_DEBUG


disable TCP (default on)
enable_sctp = 0
// disable the auto discovery of local aliases based on reverse DNS on IPs (default on)

add local domain aliases

// port to listen to can be specified more than once if needed to listen on many ports
#!ifdef WITH_TLS

life time of TCP connection when there is no traffic – a bit higher than registration expires to cope with UA behind NAT

#!ifdef WITH_PSTN
# PSTN GW Routing
# - pstn.gw_ip: valid IP or hostname as string value, example:
# pstn.gw_ip = "" desc "My PSTN GW Address"
# - by default is empty to avoid misrouting
pstn.gw_ip = "" desc "PSTN GW Address"
pstn.gw_port = "" desc "PSTN GW Port"

# 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"

Modules Section

set paths to location of modules (to sources or installation folders)


#!ifdef WITH_MYSQL
loadmodule ""

loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""
loadmodule ""

#!ifdef WITH_AUTH
loadmodule ""
loadmodule ""
loadmodule ""

loadmodule ""

loadmodule ""

loadmodule ""

loadmodule ""
loadmodule ""

#!ifdef WITH_NAT
loadmodule ""
loadmodule ""

#!ifdef WITH_TLS
loadmodule ""

loadmodule ""
loadmodule ""

loadmodule ""

#!ifdef WITH_DEBUG
loadmodule ""

loadmodule ""
#loadmodule ""
loadmodule ""

----- mi_fifo params -----
#modparam("mi_fifo", "fifo_name", "/var/run/kamailio/kamailio_fifo")</pre>

----- ctl params -----
#modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl")</pre>

----- 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)</pre>

----- 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)</pre>

enhanced DB accounting

#!ifdef WITH_ACCDB

modparam("acc", "db_flag", FLT_ACC)

modparam("acc", "db_missed_flag", FLT_ACCMISSED)

modparam("acc", "db_url", DBURL)

modparam("acc", "db_extra",




usrloc params – enable DB persistency for location entries


modparam("usrloc", "db_url", DBURL)

modparam("usrloc", "db_mode", 2)

modparam("usrloc", "use_domain", MULTIDOMAIN)


auth_db params

#!ifdef WITH_AUTH

modparam("auth_db", "db_url", DBURL)

modparam("auth_db", "calculate_ha1", yes)

modparam("auth_db", "password_column", "password")

modparam("auth_db", "load_credentials", "")

modparam("auth_db", "use_domain", MULTIDOMAIN)

permissions params


modparam("permissions", "db_url", DBURL)

modparam("permissions", "db_mode", 1)



alias_db params


modparam("alias_db", "db_url", DBURL)

modparam("alias_db", "use_domain", MULTIDOMAIN)


speeddial params


modparam("speeddial", "db_url", DBURL)

modparam("speeddial", "use_domain", MULTIDOMAIN)


domain params


modparam("domain", "db_url", DBURL)

modparam("domain", "register_myself", 1)



presence params

modparam("presence", "db_url", DBURL)

presence_xml params

modparam("presence_xml", "db_url", DBURL)
modparam("presence_xml", "force_active", 1)


rtpproxy params
modparam("rtpproxy", "rtpproxy_sock", "udp:")

nathelper params

modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
modparam("nathelper", "sipping_from", "")

params needed for NAT traversal in other modules

modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
modparam("usrloc", "nat_bflag", FLB_NATB)

tls params

#!ifdef WITH_TLS

modparam("tls", "config", "/etc/kamailio/tls.cfg")


pike params


modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 16)
modparam("pike", "remove_latency", 4)

htable params

ip ban htable with autoexpire after 5 minutes

modparam("htable", "htable", "ipban=&gt;size=8;autoexpire=300;")


xmlrpc params

modparam("xmlrpc", "route", "XMLRPC");
modparam("xmlrpc", "url_match", "^/RPC")

debugger params

#!ifdef WITH_DEBUGs
modparam("debugger", "cfgtrace", 1)

nathelper params

modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")

Note: leaving NAT pings turned off here as nathelper is <em>only</em> being used for&nbsp;WebSocket connections. NAT pings are not needed as WebSockets have&nbsp;their own keep-alives.

Routing Logic

Main SIP request routing logic processing of any incoming SIP request starts with this route

request_route { 
# per request initial checks 
    if (nat_uac_test(64)) {     
        if (is_method("REGISTER")) {          
        } else {         
            if (!add_contact_alias()) {  
                   xlog("L_ERR", "Error aliasing contact \n");             
                   sl_send_reply("400", "Bad Request");                    exit;         }     } } 
# NAT detection 
# CANCEL processing 
if (is_method("CANCEL")) {     
    if (t_check_trans()) {         

# handle requests within SIP dialogs 
### only initial requests (no To tag) 
# handle retransmissions 
if(t_precheck_trans()) { 

# authentication 

# record routing for dialog forming requests (in case they are routed) - remove preloaded route headers 

if (is_method("INVITE|SUBSCRIBE")) 

# account only INVITEs 
if (is_method("INVITE")) {     
    setflag(FLT_ACC); # do accounting 
# dispatch requests to foreign domains 

### requests for my local domains 
# handle presence related requests 

# handle registrations 
if ($rU==$null) {     
# request with no Username in RURI     sl_send_reply("484","Address Incomplete");     
# 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|SUBSCRIBE|UPDATE”)) {
if (is_method(“INVITE”)) {
if (!t_relay()) {

Per SIP request initial checks

route[REQINIT] { #!ifdef WITH_ANTIFLOOD # flood detection from same IP and traffic ban for a while # be sure you exclude checking trusted peers, such as pstn gateways – local host excluded (e.g., loop to self) 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 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

route[WITHINDLG] {
    if (!has_totag()) return;

    if (has_totag()) {

#sequential request withing a dialog should take the path determined by record-routing

        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");

#sequential request within a dialog should  take the path determined by record-routing
    if (loose_route()) {
        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
        else if ( is_method("NOTIFY") ) {
            # Add Record-Route for in-dialog NOTIFY as per RFC 6665.

    if (is_method("SUBSCRIBE") && uri == myself) {
    # in-dialog subscribe requests

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
    } else {
        # ACK without matching transaction ... ignore and discard

sl_send_reply("404","Not here");

Handle SIP registrations

User location service

route[LOCATION] {

# search for short dialing - 2-digit extension

# search in DB-based aliases

$avp(oexten) = $rU;
if (!lookup("location")) {
    $var(rc) = $rc;
    switch ($var(rc)) {
        case -1:
        case -3:
           send_reply("404", "Not Found");
        case -2:
           send_reply("405", "Method Not Allowed");

# when routing via usrloc, log the missed calls also
if (is_method("INVITE")) {


Presence server processing

route[PRESENCE] {


if(is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
    # returns here if no voicemail server is configured
    sl_send_reply("404", "No voicemail service");

if (!t_newtran()) {

if(is_method("PUBLISH")) {
} else if(is_method("SUBSCRIBE")) {

# if presence enabled, this part will not be executed
if (is_method("PUBLISH") || $rU==$null) {
    sl_send_reply("404", "Not here");

IP authorization and user authentication

route[AUTH] {
#!ifdef WITH_AUTH

if((!is_method("REGISTER")) && allow_source_address()) {
    # source IP allowed

if (is_method("REGISTER") || from_uri==myself)
    # authenticate requests
    if (!auth_check("$fd", "subscriber", "1")) {
        auth_challenge("$fd", "0");

    # user authenticated - remove auth header

# 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");


Caller NAT detection

route[NATDETECT] {
#!ifdef WITH_NAT

if (nat_uac_test("19")) {
    if (is_method("REGISTER")) {
    } else {

RTPProxy control and signaling updates for NAT traversal

route[NATMANAGE] {

#!ifdef WITH_NAT
if (is_request()) {
    if(has_totag()) {
        if(check_route_param("nat=yes")) {
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB)))


if (is_request()) {
    if (!has_totag()) {
        if(t_is_branch_route()) {

if (is_reply()) {
    if(isbflagset(FLB_NATB)) {


URI update for dialog requests

route[DLGURI] {
#!ifdef WITH_NAT
if(!isdsturiset()) {

Routing to foreign domains

route[SIPOUT] {
if (uri==myself) return;

append_hf("P-hint: outbound\r\n");

PSTN GW routing

route[PSTN] {
#!ifdef WITH_PSTN
# check if PSTN GW IP is defined
if (strempty($sel(cfg_get.pstn.gw_ip))) {
xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");

# route to PSTN dialed numbers starting with '+' or '00'
# (international format)
# - update the condition to match your dialing rules for PSTN routing

# only local users allowed to call
if(from_uri!=myself) {
sl_send_reply("403", "Not Allowed");

if (strempty($sel(cfg_get.pstn.gw_port))) {
$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
} else {
$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":"
+ $sel(cfg_get.pstn.gw_port);



XMLRPC routing

route[XMLRPC] {
# allow XMLRPC from localhost
if ((method=="POST" || method=="GET")
&& (src_ip== {
# close connection only for xmlrpclib user agents (there is a bug in
# xmlrpclib: it waits for EOF before interpreting the response).
if ($hdr(User-Agent) =~ "xmlrpclib")
send_reply("403", "Forbidden");

Routing to voicemail server


# check if VoiceMail server IP is defined
if (strempty($sel(cfg_get.voicemail.srv_ip))) {
xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n");
if(is_method("INVITE")) {
$ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)
+ ":" + $sel(cfg_get.voicemail.srv_port);
} else {
$ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip)
+ ":" + $sel(cfg_get.voicemail.srv_port);


Manage outgoing branches

branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");

Manage incoming replies

onreply_route[MANAGE_REPLY] {
xdbg("incoming reply\n");

Manage failure routing cases

failure_route[MANAGE_FAILURE] {

if (t_is_canceled()) {

# block call redirect based on 3xx replies.
if (t_check_status("3[0-9][0-9]")) {
    t_reply("404","Not found");

# serial forking
# - route to voicemail on busy or no answer (timeout)
if (t_check_status("486|408")) {
    $du = $null;

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.


Helps to configure and database needed by kamailio . First we need to select a database engine in the kamctlrc file by DBENGINE parameter .


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.


send RPC commands to Kamailio from command line , requires  ctl module


web management interface for Kamailio, written in PHP , AJAX , web 2.0 using MVC architecture

  • system and database administration tools for Kamailio SIP Server
  • subscriber, database aliases and speed dial management
  • location table view
  • dispatcher (load balancer), prefix-domain translation and least cost routing (lcr) management
  • access control lists (user groups) and permissions management
  • accounting records and missed calls vies
  • manage call data records (generated from acc records)
  • hash table, dial plan table and user preferences table management
  • offline message storage, presence service and sip trace views
  • communication with Kamailio SIP Server via XMLRPC ,  JSONRPC
  • communication with FreeSWITCH via event socket
  • create and display charts from statistic data stored by Kamailio
  • user location statistics charts
  • SIP traffic load charts
  • memory usage charts
  • accounting records charts and summary table
  • SQL-based CDR generation and rating billing engine


cmd line client written Python



SIP registration processing logic can be defined here .

Path support – off , lazy , strict

Things covered in this article

  • Internal architecture
  • Configuration language
  • least cost routing
  • load balancing
  • traffic dispatching
  • DID routing
  • prefix based routing
  • SIP trunks and peering
  • traffic shaping
  • topology hiding
  • flood detection
  • scanning attacks prevention
  • anti-fraud policies

SQL and noSQL connectors

enum and DNS based routing

authentication and authorization

secure communication (TLS)

registration and location services

accounting and call data records

call control – redirect, forward, baring

redundancy and scalability

high availability and failover

websockets and webrtc

References :

Henning Westerholt – Kamailio project-1&1 Internet AG ( 2009 )


This post describes the installation , setup and configuration of Office SIP server to provide a registrar to our SIP based WebRTC application .

1. Get office SIP from this website


2. Downloaded office sip executable on windows looks like this . double click on it to start installation .


3.Installation screen appears as follows


4. Terms and conditions


5. Destination folder for installation


6. Installing


7. Validating install


8. Installation completed


9. Launch icon on dekstop


10 . Office SIP web login screen


11. create account ( also known as realm or domain ) for users to register in their SIP and webrtc sip agents


12. Fill in account details for every account added to officeSIP


13. add users that will be registering to officeSIP server


14.Office SIP settings file can be modified for changing server parameters like ip and port


15 . Office SIP can now be used by sip agents like softphones , webRTC pages , etc to register with OfficeSIP server

BEA Weblogic SIP server

Bea server is a old SIP servlet container ie application server which is used to embed control logic in a program . It is supported on jdk1.5 hence the system’s environment variables must match . Otherwise in later stages deploying applications throw class version error .

1. Install Bea Weblogic

2. Follow the Installation steps

Make domain

3. Goto the installation directory . Usually C:/bea/user_projects/mydomain/ .

click on startweblogic.cmd in windows. In case the system is linux run script

4. Open Web console on url : Enter username password

default username password weblogic , weblogic .

It can also be customized for example my username and password are altanai , tcs@1234

5.  Make Converged SIP Servlet Application in any editor such as notepad , edit+ etc .

The project structure looks like

Call screening

The SIP servlet are put side directory structure of src

For example : sample application for Call screening

package com.altanai.voice;
import javax.servlet.*;
import javax.servlet.sip.*;
import javax.servlet.sip.Proxy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.*;
public class CallScreening extends SipServlet
private static SipFactory factory;
private static SipApplicationSession sas;
private static Proxy proxy;
public void init(ServletConfig config) throws ServletException
System.out.println(“Call screening SIP servlet initiated”);
protected void doInvite(SipServletRequest req) throws java.lang.IllegalArgumentException,java.lang.IllegalStateException,javax.servlet.ServletException,
System.out.println(“Received an Invite Request”);
System.out.println(“User is blocked”);
System.out.println(“User is not blocked”);

6. Build it with ant . For this go inside the application folder and run ant. Output will either be “failed to build “ or “build successfully” .

The ant  command generates the war file from SIP servlet Web application .

7. Incase of successful build . Add the application to Weblogic web console install section and activate it .

I will demonstrate this process in step by step manner . First  click on “ Lock and Edit “ Button on the left panel . Then goto Install button in the centre area and browser to the location of application war or sar we have build through ant ,

8. We can delete an application in exactly the same way . click on “ Lock and Edit “ Button on the left panel . Then goto the delete button after selecting the radio button alongside the application we want to delete.

8. For enhanced application building we can also refer to sample provided along with bea weblogic . file:///C:/bea/sipserver30/samples/sipserver/examples/src/index.html

Mobicents SIP server platform

The Mobicent server bears 50% resemblance to Rhino TAS .
So far , I have successfully done the following

1. installed the Mobicent platform on Linux machine
2. set up the environment to build and deploy the applications .
3. Ran simple sip b2bua call using sipp .

Attached are the screen shots of the same .

1. User agent client (UAC) Dialog
2. User agent server (UAS) Dialog
3. Mobicent slee management console
4. Joboss status console
5. Admin console depicting applications installed .

Freeswitch Modules

This section describes some of the popular and useful freeswitch module . Although there are many more modules , I have picked a few of commonly used one and divided them into following categories :

  • Loggers
  • XML Interfaces
  • Event Handlers
  • Application
  • Language




mod_enum is a dialplan interface, an application interface and an api command interface

XML Interfaces



Event Handlers



log call detail records (CDRs) to a text file using text generation templates as in /conf/autoload_configs/cdr_csv.conf.xml

<configuration name="cdr_csv.conf" description="CDR CSV Format">
<param name="default-template" value="example"/>
<param name="rotate-on-hup" value="true"/>
<!-- may be a b or ab -->
<param name="legs" value="a"/>
<template name="sql">INSERT INTO cdr VALUES ("${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}");</template>


Directory Interfaces


When any of the endpoints are loaded , they start listening for connection using configuration file . Dialstring identifies the recipient of the channel such as sofia/external/098099999 where sofia is the dial string prefix for SIP.

mod_sofia – SIP protocol support

mod_gsmopen –  Supports voice & SMS over a GSM network

mod_h323 – H.323 , ITU rich media communication protocol.

mod_opal – IAX2

mod_skypopen – Skype (discontinued )

mod_dingaling – Jingle , Google Talk, XMPP integration ( discontinued )





mod_freetdm – Provides support for telephony cards from manufacturers such as Digium, Sangoma and Zaptel. Can communicate in most legacy telephony protocols such as ISDN, SS7 & analog





RTMP protocol is primarily used by Flash for streaming audio, video, and data over the Internet.





inbound and outbound conference bridge, loaded from file  conf/autoload_configs/conference.conf.xml




Dialplan tools provide the apps (commands) to process call sessions in XML dialplans.


Answer the call for a channel.

<!-- a sample IVR( Interactive Voice Response ) -->
<extension name="ivr">
<condition field="destination_number" expression="^9000$">
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="ivr" data="demo_ivr"/>


Attended Transfer.


Execute an operating system command in the background.

bind_digit_action – Bind a key sequence or regex to an action.


Respond to certain DTMF sequences on specified call leg(s) during a bridge and execute another dialplan application.


Block DTMFs from being sent or received on the channel.


Cancel an application currently running on the channel.


Bridge a new channel to the existing one.


Export a channel variable across any bridge.


Capture data into a channel variable.


Send a text message to an IM client


Block originating address unless it matches an ACL.Test the i.p. address that originates the call against an Access Control List or CIDR mask

  • clear_digit_action – Clear all digit bindings
  • clear_speech_cache – Clear speech handle cache.
  • cluechoo – Console-only “ConCon” choo-choo train
  • cng_plc – Packet Loss Concealment on lost packets + comfort noise generation
  • conference – Establish an inbound or outbound conference call
  • db – insert information into the database.
  • deflect – Send a call deflect/refer.
  • delay_echo – Echo audio at a specified delay.
  • detect_speech – Implements speech recognition.
  • digit_action_set_realm – Change binding realm.
  • displace_session – Displace audio on a channel.
  • early_hangup – Enable early hangup on a channel.


Spy on a channel.

<extension name="eavesdrop">
<condition field="destination_number" expression="^88(\d{4})$|^\*0(.*)$">
    <action application="answer"/>
    <action application="eavesdrop" data="${hash(select/${domain_name}-spymap/$1$2)}"/>


Echo audio and video back to the originator.


Enable Media Heartbeat.


Continuously play file to caller.

enum – Perform E.164 lookup.
erlang – Handle a call using Erlang.
eval – Evaluates a string.
event – Fire an event.


Execute an extension from within another extension and return.


Export a channel variable across a bridge <varname>=<value>

fax_detect – Detect FAX CNG – may be deprecated.
fifo – Send caller to a FIFO queue.
fifo_track_call – Count a call as a FIFO call in the manual_calls queue.
flush_dtmf – Flush any queued DTMF.
gentones – Generate TGML tones.
group – Insert or delete members in a group.


Hang up the current channel.

<extension name="show_info">
<condition field="destination_number" expression="^9192$">
<action application="answer"/>
<action application="info"/>
<action application="sleep" data="250"/>
<action application="hangup"/>

hash – Add a hash to the db.
hold – Send a hold message.


Send call control to a Web server with the HTTAPI infrastructure

info – Display Call Info.
intercept – Lets you pickup a call and take it over if you know the uuid.


Run an IVR menu.

javascript – Run a JavaScript script from the dialplan
jitterbuffer – Send a jitter buffer message to a session
limit – Set a limit on number of calls to/from a resource
limit_execute – Set the limit on a specific application
limit_hash – Set a limit on number of calls to/from a resource
limit_hash_execute – Set the limit on a specific application
log – Logs a channel variable for the channel calling the application
loop_playback – Playback a file to the channel looply for limted times
lua – Run a Lua script from the dialplan
media_reset – Reset all bypass/proxy media flags.
mkdir – Create a directory.
multiset – Set multiple channel variables with a single action.
mutex – Block on a call flow, allowing only one at a time
page – Play an audio file as a page.
park – Park a call.
park_state – Park State.
phrase – Say a Phrase.
pickup – Pickup a call.
play_and_detect_speech – Play while doing speech recognition.
play_and_get_digits – Play and get Digits.
play_fsv – Play an FSV file. FSV – (FS Video File Format) additional description needed
playback – Play a sound file to the originator.
pre_answer – Answer a channel in early media mode.[old wiki]
preprocess – description needed
presence – Send Presence
privacy – Set caller privacy on calls.
queue_dtmf – Send DTMF digits after a successful bridge.
read – Read Digits.
record – Record a file from the channel’s input.
record_fsv – Record a FSV file. FSV – (FS Video File Format) additional description needed
record_session – Record Session.
recovery_refresh – Send a recovery refresh.
redirect – Send a redirect message to a session.
regex – Perform a regex.
remove_bugs – Remove media bugs.
rename – Rename file.
respond – Send a respond message to a session.
ring_ready – Indicate Ring_Ready on a channel.
rxfax – Receive a fax as a tif file.


Say time/date/ip_address/digits/etc. With pre-recorded prompts.
sched_broadcast – Enable Scheduled Broadcast.
sched_cancel – Cancel a scheduled future broadcast/transfer.
sched_hangup – Enable Scheduled Hangup.
sched_heartbeat – Enable Scheduled Heartbeat.
sched_transfer – Enable Scheduled Transfer.
send_display – Sends an info packet with a sipfrag.
send_dtmf – Send inband DTMF, 2833, or SIP Info digits from a session.
send_info – Send info to the endpoint.
session_loglevel – Override the system’s loglevel for this channel.
set – Set a channel variable for the channel calling the application.
set_audio_level – Adjust the read or write audio levels for a channel.
set_global – Set a global variable.
set_name – Name the channel.
set_profile_var – Set a caller profile variable.
set_user – Set a user.
set_zombie_exec – Sets the zombie execution flag on the current channel.
sleep – Pause a channel.
socket – Establish an outbound socket connection.
sound_test – Analyze Audio.
speak – Speaks a string or file of text to the channel using the defined TTS engine.[old wiki]
soft_hold – Put a bridged channel on hold.
start_dtmf – Start inband DTMF detection.
stop_dtmf – Stop inband DTMF detection.
start_dtmf_generate – Start inband DTMF generation.
stop_displace_session – Stop displacement audio on a channel.
stop_dtmf_generate – Stop inband DTMF generation.
stop_record_session – Stop Record Session.
stop_tone_detect – Stop detecting tones.
strftime – Returns formatted date and time.
system – Execute an operating system command.
three_way – Three way call with a UUID.
tone_detect – Detect the presence of a tone and execute a command if found.
transfer – Immediately transfer the calling channel to a new extension.[old wiki]
translate – Number translation.
unbind_meta_app – Unbind a key from an application.
unset – Unset a variable.
unhold – Send a un-hold message.
verbose_events – Make ALL Events verbose (Make all variables appear in every single event for this channel).
wait_for_silence – Pause processing while waiting for silence on the channel.
wait_for_answer – Pause processing while waiting for the call to be answered.


chat – Send a text message to a IM client.
presence – Send Presence.
strepoch – Returns the date/time as a UNIX epoch (seconds elapsed since midnight UTC, January 1, 1970).
strftime – Returns formatted date and time.
strftime_tz – Returns formatted date and time in the timezone specified.

SNOM Module

This one only works on Linux for now

Dialplan Interfaces

Codec Interfaces

File Format Interfaces
For icecast/mp3 streams/files
For local streams (play all the files in a directory)




These scripting languages allow programming the call routing logic


FreeSWITCH has support for the Google V8 JavaScript (ECMAScript) engine. It needs to be uncommented in the modules.conf file

Screen Shot 2018-09-27 at 6.34.04 PM











Third party modules


FreeSwitch SIP and Media Server

FreeSWITCH is free and open source communications software licensed under Mozilla Public License. It if often the core of voice core to provider call routing and media control . Its core library, libfreeswitch, is capable of being embedded into other projects, as well as being used as a stand-alone application.

 FreeSWITCH is designed to route and interconnect popular communication protocols using audio, video, text, or any other form

of media. First released in January 2006, FreeSWITCH has grown to become the world’s premier open source soft-switch

platform. This versatile platform is used to power voice, video, and chat communications on devices ranging from single calls on

a Raspberry Pi to large server clusters handling millions of calls. FreeSWITCH powers a number of commercial products

from start-ups to Carriers.


It can perform the functions of  ( but not limited to )

  • PBX Server (Transcoding B2BUA)
  • IVR & Announcement Server
  • Conference host
  • Voicemail
  • Session Border Controller
  • Text to Speech (TTS)
  • VOIP endpoint
  • Class 5 softswitch

Freeswitch has a modular architecture which is both scalable and customisable. The most important modules are , Endpoint , dialplan and Application .

Application is the instruction added for a particular dial plan with an extension object. Data Arguments are also passed to an application. Examples like Set: configure extension parameter , Bridge: bridge a new channel to the existing one , Answer: answer the call for a channel , Hangup: hangup a current channel , Run an IVR menu etc

Protocols set up call legs/ channels , negotiate codecs and stream media.The endpoint module helps to bridge channels between different protocol supported endpoints . SIP being the most popular protocol for voip session is implemented by mod_sofia module while RTP is inbuild into freeswitch core . SRTP ( media protocol for webrtc ) is provided by mod_verto.

Architecture and Design of Freeswitch

Freeswitch can form the basis of complicated and sophisticated communications backend framework with thousand CPS(Call per second ) . It can connect to VOIP ( voice over IP ) as well as PSTN ( Public Switched Telephone network ) and PRI ( Primary Rate Interfaces – used in enterprises communication)


Data strutters are opaque and operations can be invoke by APIs with routines getting maximum reuse .

Threaded Model 

Enables parallel operation as every connection has its own thread. Event handlers push incoming events into threads .  Sub system run in background threads .


Channel Variables

Channel variables are used to manipulate dialplan execution, to control call progress, and to provide options to applications. They play a pervasive role, as FreeSWITCH™ frequently consults channel variables as a way to customize processing prior to a channel’s creation, during call progress, and after the channel hangs up.


  • $${variable} is expanded once when FreeSWITCH™ first parses the configuration on startup or after invoking reloadxml. It is suitable for variables that do not change, such as the domain of a single-tenant FreeSWITCH™ server.

<param name=”domain” value=”$${domain}”/>

  • ${variable} is expanded during each pass through the dialplan, so it is used for variables that are expected to change, such as the ${destination_number} or ${sip_to_user} fields.

Setting a channel variable :

<application="set" data="rtp_secure_media=true"/>

Reading a channel variable:

<route service="E2U+SIP" regex="sip:(.*)" replace="sofia/${use_profile}/$1;transport=udp"/>

Exporting channel variables in bridge operations

  • from one to another call leg using export_var
  • exporting to a list using export application
<action application="export" data="dialed_extension=$1"/>

Custom channel variables can be defined anytime too such as

<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss"/>

Also channel variables can be limited to scope on an extension . An example of passing some channel variable to log application .

<action application="log" data="INFO Inbound call CallUUID ${call_uuid} SIPCallID ${sip_call_id}- from ${caller_id_number} to ${destination_number}"/>

If the conditions are not met, optional anti-actions are executed.

<name="is_secure" continue="true">
<-- Only Truly consider it secure if its TLS and SRTP -->
<condition field="${sip_via_protocol}" expression="tls"/>
<condition field="${rtp_secure_media_confirmed}" expression="^true$">
    <action application="sleep" data="2000"/>
    <action application="playback" data="misc/call_secured.wav"/>
    <anti-action application="eval" data="not_secure"/>

Inline actions are executed during the hunting phase of dialplan


A Dialplan is designed to lookup list of instructions from the central XML registry within FreeSWITCH. In general dialplans are used to route a dialed call to an endpoint based on the extension and its  condition. When a matching extension is found , it executes its actions . The combination of the above can create detailed control and call flow plans . FS uses Perl-compatible regular expressions (PCRE) for pattern matching. Few formats

  • sofia/profile2/8765@ , will dial out 8765 at host using profile2
  • sofia/gateway/ , will dial through a Gateway (SIP Provider) to user 5432
  • sofia/profile2/8765@;transport=tcp , dialing with specific transport like TCP, UDP, TLS, or SCTP.
  • {absolute_codec_string=PCMU}sofia/external/sip:9106@${local_ip_v4}:5080 , to specify the codecs

Speak Time and Date on Call

when dialed number matches regular expression 9172 , then call is answered , put to sleep for 1 seconds and using say application current date and time is said , then application hangs up .

<extension name="speak_date_time" >
<condition field="destination_number" expression="^9172$">
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="say" data="en CURRENT_DATE_TIME pronounced ${strepoch()}"/>
    <action application="hangup"/>

There may be 3 kinds of contexts  :

  1. default  : used for all internal users  such as PBX . Local_Extension can route the call between internal users .
  2. public  : used by external world users such as DID
  3. features : other custom in call features using bind_meta_app application etc

Call Routing based on destination number and forwarding to voice mail on no answer

Configure the sip driver to use the custom context while processing the call such as ,

<profile name="telco_custom_sipprofile">
    <param name="context" value="custom_sipcontext"/>

When call arrives for destination 501 , the condition matches and this blocks action are executed such as in example below .
Exetnsion 501 rings , when not answered it sleeps or 1 seconds , then gets forwarded to voice mail .

If the call to 501 was answered ie handed off then further actions would not be executed

<context name="custom_sipcontext">
<extension name="501">
<condition field="destination_number" expression="^501$">
    <action application="bridge" data="user/501"/>
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>

Call routing based on day and time

<extension name="Time of day, day of week setup" continue="true">
<condition wday="2-6" hour="8-16 break="never">
<action application="set" data="office_status=open" inline="true"/>
<anti-action application="set" data="office_status=closed" inline="true"/>
<condition wday="2-6" time-of-day="1:30-2:30" break="never">
<action application="set" data="office_status=lunch" inline="true"/>

inline= true states that channel variables will be used for later reference while break=never and continue=true tell the program to keep looking for more condition matches incase of failed or successful match respectively

Match incoming network IP address with pre configured IP

Store incoming number to $1 variable and bridge the call with custom profile . Read more about sip profiles in sections below .

<extension name="ipmatch">
<condition field="network_addr" expression="^198\.168\.1\.0$"/>
<condition field="destination_number" expression="^(\d+)$">
    <action application="bridge" data="sofia/customprofile/$1@"/>

Note : $1 varibles value is not available outside of the condition block
Store captured values in standard variables 

<action application=”set” data=”domain_name=$${domain}”/>

Following example store stores destination_number ( freeswitch variable ) into ‘dialed_number’

<extension name="ipmatch_variable">
<condition field="destination_number" expression="^(\d+)$">
    <action application="set" data="dialed_number=$1"/>
<condition field="network_addr" expression="^192\.168\.1\.1$">
    <action application="bridge" data="sofia/customprofile/${dialed_number}@"/>


Media recording and playback in audio (wav)

<extension name="recording">
<condition field="destination_number" expression="^(4444)$">
    <action application="answer"/>
    <action application="set" data="playback_terminators=#"/>
    <action application="record" data="/tmp/audiofile.wav 20 200"/>

<extension name="playback">
<condition field="destination_number" expression="^(5555)$">
    <action application="answer"/>
    <action application="set" data="playback_terminators=#"/>
    <action application="playback" data="/tmp/audiofile.wav"/>

Routing by listening on the audio stream for a touch-tone * followed by a single digit.

If the called user dials *1, then the execute_extension::dx XML features command is executed.

<extension name="Local_Extension">
<condition field="destination_number" expression="^(10[01][0-9])$">
    <action application="export" data="dialed_extension=$1"/>
    <!-- bind_meta_app can have these args <key> [a|b|ab] [a|b|o|s] <app> -->
    <action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
    <action application="bind_meta_app" data="2 b s record_session::${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
    <action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
    <action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/>

The dx extension in features accepts the digits and proceeds as defined with the call

<extension name="dx">
<condition field="destination_number" expression="^dx$">
    <action application="answer"/>
    <action application="read" data="11 11 'tone_stream://%(10000,0,350,440)' digits 5000 #"/>
    <action application="execute_extension" data="is_transfer XML features"/>

Some authentication and security related dialplan applications :-

Checking user is authenticated before routing call , else respond 407

<extension name="9191">
<condition field="destination_number" expression="^9191$"/>
<condition field="${sip_authorized}" expression="true">
    <anti-action application="respond" data="407"/>
    <action application="playback" data="misc/connected_securly.wav"/>

Checking if there is TLS and SRTP security , else set not_secure

<extension name="is_secure">
<condition field="${sip_via_protocol}" expression="tls"/>
<condition field="${rtp_secure_media_confirmed}" expression="^true$">
<action application="sleep" data="1000"/>
<action application="playback" data="misc/connected_securly.wav"/>
<anti-action application="eval" data="not_secure"/>

Catching invalid destinations or extensions

Catch numbers which didnt match any other case. Add this extension to bottom. It plays an invalid tune

<extension name="catchall">
<condition field="destination_number" expression=".*" continue="true">
    <action application="playback" data="misc/invalid_extension.wav"/>

Call screening and blocking dialplan applications

Call Screening by name announcement

User caller’s name store in wave file

<action application="set" data="call_screen_filename=/tmp/${caller_id_number}-name.wav"/>

Connect to the called party. On answer announce the name. since playback_terminators is set to digits , pressing any one of them will terminate the call

<action application="set" data="hangup_after_bridge=true" />
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="phrase" data="voicemail_record_name"/>
<action application="playback" data="tone_stream://%(500, 0, 640)"/>
<action application="set" data="playback_terminators=#*0123456789"/>
<action application="record" data="${call_screen_filename} 7 200 2"/>

If called party presses 1 connect the call, or hang up.

<action application="set" data="group_confirm_key=1"/>
<action application="set" data="fail_on_single_reject=true"/>
<action application="set" data="group_confirm_file=phrase:screen_confirm:${call_screen_filename}"/>
<action application="set" data="continue_on_fail=true"/>
<action application="bridge" data="user/$1"/>

If the called party hangs up, the caller is connected with voicemail.

<action application="voicemail" data="default ${domain} $1"/>

finally hangup

<action application="hangup"/>

Block caller

Dial *77 followed by the number to be blocked

<extension name="block_caller_id">
<condition field="destination_number" expression="^\*77(\d+)$">
<action application="privacy" data="full"/>
<action application="set" data="sip_h_Privacy=id"/>
<action application="set" data="privacy=yes"/>
<action application="transfer" data="$1 XML default"/>

Block certain codes

block certain NPAs that you do not want to terminate based on caller id area codes and respond with SIP:503 to your origination so that they can route advance if they have other carrier to terminate to.

<extension name="blocked_cid_npa">
<condition field="caller_id_number" expression="^(\+1|1)?((876|809)\d{7})$">
<action application="respond" data="503"/>
<action application="hangup"/>

DID – Direct Inward Dialling via dialplan Public.xml

Assume we have a DID number 676767 which is served by telco provider either over SIP trunk/PRI lines . When someone from external world calls this number , FE needs to route the call to an internal user for example user at extension 3003 ( in default .xml context)

<extension name="public_did">
<condition field="destination_number" expression="^\+?1?(676767)$">
    <action application="set" data="domain_name=${domain}"/>
    <action application="transfer" data="3003 XML default"/>

If we are on multi domain setup , we need to setup the domain correctly .$${domain} is the default domain set from vars.xml but you can set it to any domain we have setup in user directory. Added the extra characters in from of DID number to adjust for various ISD code and number formats suffixes such as +1- ,91- , 0- etc .

IVR ( Interactive Voice Respondent ) using Menu

Main Menu – uses tts enginer and 3 attempsts to repond with timeout 10 seconds
On pressing 1 – bridge the call to conference , on press 2 – transfer to 2222 using default
On press of 3 – transfer using enum while on press 4 – play submenu. On press of 9 – goto top menu

<menu name="demo_ivr"
greet-long="say:Press 1 to join the conference, Press 2 to transfer , 3 to transfer , 4 to goto another menu "
    <entry action="menu-exec-app" digits="1" param="bridge sofia/${domain}/"/>
    <entry action="menu-exec-app" digits="2" param="transfer 2222 XML default"/> 
    <entry action="menu-exec-app" digits="3" param="transfer 1234*256 enum"/> 
    <entry action="menu-sub" digits="4" param="demo_ivr_submenu"/> 
    <entry action="menu-exec-app" digits="/^(10[01][0-9])$/" param="transfer $1 XML features"/>
    <entry action="menu-top" digits="9"/> 

Submenu – press * to repeat menu , # to exit . the timeout is 15 seconds

<menu name="demo_ivr_submenu"
    <entry action="menu-top" digits="*"/>
    <entry action="menu-exit" digits="#"/>

Find me Follow Me

If a users has lets say 3 phone – home , office and car then an incomming call should subesquently ring everywhere one by one till the user picks up the phone closet to him . leg_delay_start is the timer after which this endpoint will start riniging and leg_timeout is the duration till when this endpoint will ring.
Therfore as per below sample homephone will ring , after 5 sceonds office phone will ring and after 15 secons his cellphone 987654321 will ring . after 25 seconds call will end.

<action application="bridge" data="user/, 
[leg_delay_start=15,leg_timeout=25] sofia/gateway/flowroute/987654321" />

DID can bridge to multiple extensions or gateways sequentially in a hunt pattern

<extension name="did_hunt">
<condition field="destination_number" expression="87654321">

<action application="set" data="hangup_after_bridge=true"/>
<action application="set" data="continue_on_fail=true"/>

<!-- this is needed to allow call_timeout to work after bridging to a gateway -->
<action application="set" data="ignore_early_media=true"/>

<!-- ring desk extension for 10 seconds. -->
<action application="set" data="call_timeout=10"/>
<action application="bridge" data="sofia/${domain}/1001"/>

<!-- Now try cell phone, hangup after 13 -->
<action application="set" data="call_timeout=13"/>
<action application="bridge" data="sofia/gateway/voicepulse/987654321" />

<!-- No answer, transfer to voicemail -->
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="voicemail" data="default ${domain} 1001"/>


Ring Multiple Targets

<action application="bridge" 
user/7010@${domain}, user/7022@${domain}, user/7007@${domain}, 

Handle Failures and Early Media

<action application="bridge" 
data="{ ignore_early_media=true, 
destination_out_of_order:2:1776.7 }

To detect early media fail the conditions are
user busy – number of attempts is 3 and 480Hz 620Hz is the tone of frequency which is standard busy tone.
destination out of order – number of attempts 2 , 1776.7 Hz frequency .
Note that as per condition only these frequencies are detected for action , others are ignored .


A simple directory listing containing two groups with 2 users each

<domain name="${domain}">
<param name="dial-string" value="{^^:sip_invite_domain=${dialed_domain}:

<variable name="record_stereo" value="true"/>
<variable name="default_gateway" value="${default_provider}"/>
<variable name="default_areacode" value="${default_areacode}"/>
<variable name="transfer_fallback_extension" value="operator"/>

<group name="default">
        <X-PRE-PROCESS cmd="include" data="default/*.xml"/>

<group name="team1">
        <user id="1000" type="pointer"/>
        <user id="1001" type="pointer"/>

<group name="team2">
        <user id="1002" type="pointer"/>
        <user id="1003" type="pointer"/>


1001 user’s xml

<user id="1001">
<param name="password" value="${default_password}"/>
    <variable name="toll_allow" value="domestic,international,local"/>
    <variable name="accountcode" value="1001"/>
    <variable name="user_context" value="default"/>
    <variable name="effective_caller_id_name" value="Extension 1001"/>
    <variable name="effective_caller_id_number" value="1001"/>
    <variable name="outbound_caller_id_name" value="${outbound_caller_name}"/>
    <variable name="outbound_caller_id_number" value="${outbound_caller_id}"/>
    <variable name="callgroup" value="team1"/>

Adding users

/usr/src/freeswitch-debs/freeswitch# scripts/perl/add_user 3000

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
 LANGUAGE = (unset),
 LC_ALL = (unset),
 LC_CTYPE = "UTF-8",
 LANG = "en_US.UTF-8"
    are supported and installed on your system.

perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
Added 3000 in file /usr/local/freeswitch/conf/directory/default/3000.xml 
Operation complete. 1 user added.
Be sure to reloadxml.
Regular expression information:
            Sample regex for all new users: ^3000$
Sample regex for all new AND current users: ^(10(0[0-9]|1[0-9]|20)|3000)$

In the default configuration you can modify the expression in the condition for 'Local_Extension'.

Adding a range of users , 3000 to 3010

Since 3000 was already added previously , it threw a warning , rest were successfully added

root@ip-172-31-27-106:/usr/src/freeswitch-debs/freeswitch# scripts/perl/add_user -users=3000-3010 

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
 LANGUAGE = (unset),
 LC_ALL = (unset),
 LC_CTYPE = "UTF-8",
 LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").

User id 3000 already exists, skipping...
Added 3001 in file /usr/local/freeswitch/conf/directory/default/3001.xml 
Added 3002 in file /usr/local/freeswitch/conf/directory/default/3002.xml 
Added 3003 in file /usr/local/freeswitch/conf/directory/default/3003.xml 
Added 3004 in file /usr/local/freeswitch/conf/directory/default/3004.xml 
Added 3005 in file /usr/local/freeswitch/conf/directory/default/3005.xml 
Added 3006 in file /usr/local/freeswitch/conf/directory/default/3006.xml 
Added 3007 in file /usr/local/freeswitch/conf/directory/default/3007.xml 
Added 3008 in file /usr/local/freeswitch/conf/directory/default/3008.xml 
Added 3009 in file /usr/local/freeswitch/conf/directory/default/3009.xml 
Added 3010 in file /usr/local/freeswitch/conf/directory/default/3010.xml 
Operation complete. 10 users added.
Be sure to reloadxml.
Regular expression information:
            Sample regex for all new users: ^30(0[123456789]|10)$
Sample regex for all new AND current users: ^(10(0[0-9]|1[0-9]|20)|30(0[0-9]|10))$
In the default configuration you can modify the expression in the condition for 'Local_Extension'.

After adding the user to directory , users can now make outbound calls . But howver cannot be rechable for incoming calls . To enable that e need to add them to dialplan .

Creating dialplan for the newly added users  in conf/dialplan/default.xml

update the existing condition <condition field=destination_number expression=^(10[01][0-9])$> with <condition field=destination_number expression=^30(0[123456789]|10)$>

After this goto fs_cli cmd prompt and do reloadxml


Quick Installation on MacOS

Download and run the dmg , screenshots attached .

Building from source on Ubuntu 16.04 Xenial

*experimental not suitable for production as per Freeswitch docs

The master branch depends on video libraries which are not available as packages in Debian distribution, but are available from FreeSWITCH repository , requires the use of the devscripts and cowbuilder packages.apt-get install git devscripts cowbuilder

Change to root and add freeswitch to sources.list

wget -O - | apt-key add -
echo "deb jessie main" > /etc/apt/sources.list.d/freeswitch.list
echo "deb-src jessie main" >> /etc/apt/sources.list.d/freeswitch.list
apt-get update

apt-get build-dep freeswitch

cd /usr/src/

git clone -bv1.8 freeswitch

cd freeswitch

git config pull.rebase true

Enter freeswitch directory and Build

./ -j
make install

for errors such as “The repository ‘ xenial InRelease’ is not signed.” and “The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 0xxxxxxx” please note than only debian 8 is the officially supported os version by FS now. hence is using AWS ( amazon web service ) stick with ubuntu v 14 ie Ubuntu Server 14.04 LTS (HVM), SSD Volume Type  which is also free tier eligible.

  Ubuntu      |       Debian  
18.04  bionic     buster  / sid   - 10
17.10  artful     stretch / sid   - 9
17.04  zesty      stretch / sid
16.10  yakkety    stretch / sid
16.04  xenial     stretch / sid
15.10  wily       jessie  / sid   - 8
15.04  vivid      jessie  / sid
14.10  utopic     jessie  / sid
14.04  trusty     jessie  / sid
13.10  saucy      wheezy  / sid   - 7
13.04  raring     wheezy  / sid
12.10  quantal    wheezy  / sid
12.04  precise    wheezy  / sid
11.10  oneiric    wheezy  / sid
11.04  natty      squeeze / sid   - 6
10.10  maverick   squeeze / sid
10.04  lucid      squeeze / sid

Manual Process of bootstarp and cofigure

Once build is successfull , install libtool-bin , libcurl4-openssl-dev , libpcre3-dev , libspeex-dev , libspeexdsp-dev ,libtiff5 ,libtiff5-dev , yasm for libvpx , liblua5.1-0-dev for scripting

For mod_enum support install libldns-dev or disable it in modules.conf

we can either install libedit-dev (>= 2.11) or configure with –disable-core-libedit-support


For errors around lua file such as Cannot find lua.h header file , just do apt-get install lua5.2 and lua5.2-dev and copy the headers file manually to freeswitch languages folder such as
cp -R /usr/include/lua5.2/ src/mod/languages/mod_lua/
or you can copy these one by one lauxlib.h lua.h lua.hpp luaconf.h lualib.h

ln -s /usr/lib/x86_64-linux-gnu/ llua

sudo make install
sudo make uhd-sounds-install
sudo make uhd-moh-install
sudo make samples

If you want to make lua from source

mkdir -p ~/Developing/third_party
cd Developing
tar xf lua-5.3.2.tar.gz
cd lua-5.3.2.tar.gz
make linux 
sudo make install INSTALL_TOP=/usr/local
cd ~/Developing/third_party/rtags/build
cmake -DLUA_INCLUDE_DIR=/usr/local/include/ -DLUA_LIBRARY=/usr/local/lib/liblua.a ../
aptitude install -y -r -o APT::Install-Suggests=true freeswitch-meta-vanilla
cp -a /usr/share/freeswitch/conf/vanilla /etc/freeswitch
/etc/init.d/freeswitch start

To see if freeswitch is running  – ps aux | grep freeswitch

Screen Shot 2018-09-20 at 10.45.47 AM

To check listening ports – ngrep -W byline -d any port 5060 or netstat -lnp | grep 5060

Custom TCP RuleTCP5080 – 50810.0.0.0/0
Custom TCP RuleTCP5080 – 5081::/0
Custom UDP RuleUDP16384 – 327680.0.0.0/0
Custom UDP RuleUDP16384 – 32768::/0
All trafficAllAll0.0.0.0/0
All trafficAllAll::/0
Custom TCP RuleTCP80210.0.0.0/0
Custom TCP RuleTCP8021::/0
Custom UDP RuleUDP5060 – 50620.0.0.0/0
Custom UDP RuleUDP5060 – 5062::/0
Custom UDP RuleUDP5080 – 50810.0.0.0/0
Custom UDP RuleUDP5080 – 5081::/0
Custom TCP RuleTCP8081 – 80820.0.0.0/0
Custom TCP RuleTCP8081 – 8082::/0
Custom TCP RuleTCP5060 – 50610.0.0.0/0
Custom TCP RuleTCP5060 – 5061::/0



  • ACL
  • Fail2Ban
  • IPtables

Debugging and Call

For internal calls , originate api can be used to initiate calls such as  originate ALEG BLEG

originate {origination_caller_id_number=9999988888}sofia/internal/1004@ 91999998888 XML default CALLER_ID_NAME CALLER_ID_NUMBER

This will make a call out to sip:1004@1127.0.0.1 with the Caller ID number set to 999998888, then it will send the call to the XML dialplan using context=default. Then the dialplan will process call to 91999998888 with the Caller ID name and number specified in the fields CALLER_ID_NAME and CALLER_ID_NUMBER.

fsc_cli> originate sofia/internal/1002@ &echo()
switch_ivr_originate.c:2159 Parsing global variables
switch_channel.c:1104 New Channel sofia/internal/1002@ [5188806e-cabd-4acc-b20b-00620c3362ec]
mod_sofia.c:5026 (sofia/internal/1002@ State Change CS_NEW -> CS_INIT
switch_core_state_machine.c:584 (sofia/internal/1002@ Running State Change CS_INIT (Cur 5 Tot 122559)
switch_core_state_machine.c:627 (sofia/internal/1002@ State INIT
mod_sofia.c:93 sofia/internal/1002@ SOFIA INIT
sofia_glue.c:1299 sofia/internal/1002@ sending invite version: 1.9.0 -654-ed4920e 64bit
Local SDP:
o=FreeSWITCH 1538689496 1538689497 IN IP4
c=IN IP4
t=0 0
m=audio 24636 RTP/AVP 9 0 8 101
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
m=video 19042 RTP/AVP 102
a=rtpmap:102 VP8/90000
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 ccm tmmbr
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
switch_core_state_machine.c:40 sofia/internal/1002@ Standard INIT
switch_core_state_machine.c:48 (sofia/internal/1002@ State Change CS_INIT -> CS_ROUTING
switch_core_state_machine.c:627 (sofia/internal/1002@ State INIT going to sleep
switch_core_state_machine.c:584 (sofia/internal/1002@ Running State Change CS_ROUTING (Cur 4 Tot 122612)
sofia.c:7291 Channel sofia/internal/1002@ entering state [calling][0]
sofia.c:7291 Channel sofia/internal/1002@ entering state [terminated][503]

Ref :

My freeswitch contributor profile

Freeswitch Wiki

Freeswitch bitbucket Codebase