Category Archives: Session Initiation Prot. (SIP)

Asterisk

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

– asterisk.org

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.

– asterisk.org

Installation

goto /usr/src and download the preferred the version of asterisk code from
http://downloads.asterisk.org/pub/telephony/asterisk/

I am using the latest release candidate at the time writing this article
asterisk-16.2.0-rc1-patch.tar.gz

Some external Dependencies
apt-get install subversion

Then install the source dependencies

 sudo su
contrib/scripts/get_mp3_source.sh

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

 ./configure

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 
ldconfig

















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 markster@digium.com
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)
ip-172-31-45-26*CLI>

SIP and PJSIP modules

module show like sip
Module Description Use Count Status Support Level
chan_pjsip.so PJSIP Channel Driver 0 Running core
func_pjsip_endpoint.so Get information about a PJSIP endpoint 0 Running core
res_pjsip.so Basic SIP resource 38 Running core
res_pjsip_acl.so PJSIP ACL Resource 0 Running core
res_pjsip_authenticator_digest.so PJSIP authentication resource 0 Running core
res_pjsip_caller_id.so PJSIP Caller ID Support 1 Running core
res_pjsip_dialog_info_body_generator.so PJSIP Extension State Dialog Info+XML Pr 0 Running core
res_pjsip_diversion.so PJSIP Add Diversion Header Support 0 Running core
res_pjsip_dtmf_info.so PJSIP DTMF INFO Support 0 Running core
res_pjsip_endpoint_identifier_anonymous.so PJSIP Anonymous endpoint identifier 0 Running core
res_pjsip_endpoint_identifier_ip.so PJSIP IP endpoint identifier 0 Running core
res_pjsip_endpoint_identifier_user.so PJSIP username endpoint identifier 0 Running core
res_pjsip_exten_state.so PJSIP Extension State Notifications 0 Running core
res_pjsip_header_funcs.so PJSIP Header Functions 0 Running core
res_pjsip_logger.so PJSIP Packet Logger 0 Running core
res_pjsip_messaging.so PJSIP Messaging Support 0 Running core
res_pjsip_mwi.so PJSIP MWI resource 0 Running core
res_pjsip_mwi_body_generator.so PJSIP MWI resource 0 Running core
res_pjsip_nat.so PJSIP NAT Support 0 Running core
res_pjsip_notify.so CLI/AMI PJSIP NOTIFY Support 0 Not Running core
res_pjsip_one_touch_record_info.so PJSIP INFO One Touch Recording Support 0 Running core
res_pjsip_outbound_authenticator_digest.so PJSIP authentication resource 0 Running core
res_pjsip_outbound_publish.so PJSIP Outbound Publish Support 2 Running core
res_pjsip_outbound_registration.so PJSIP Outbound Registration Support 0 Running core
res_pjsip_path.so PJSIP Path Header Support 0 Running core
res_pjsip_pidf_body_generator.so PJSIP Extension State PIDF Provider 0 Running core
res_pjsip_pidf_digium_body_supplement.so PJSIP PIDF Digium presence supplement 0 Running core
res_pjsip_pidf_eyebeam_body_supplement.so PJSIP PIDF Eyebeam supplement 0 Running core
res_pjsip_publish_asterisk.so PJSIP Asterisk Event PUBLISH Support 0 Running core
res_pjsip_pubsub.so PJSIP event resource 11 Running core
res_pjsip_refer.so PJSIP Blind and Attended Transfer Suppor 1 Running core
res_pjsip_registrar.so PJSIP Registrar Support 0 Running core
res_pjsip_rfc3326.so PJSIP RFC3326 Support 0 Running core
res_pjsip_sdp_rtp.so PJSIP SDP RTP/AVP stream handler 0 Running core
res_pjsip_send_to_voicemail.so PJSIP REFER Send to Voicemail Support 0 Running core
res_pjsip_session.so PJSIP Session resource 14 Running core
res_pjsip_t38.so PJSIP T.38 UDPTL Support 0 Running core
res_pjsip_transport_websocket.so PJSIP WebSocket Transport Support 0 Not Running core
res_pjsip_xpidf_body_generator.so 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

-tbd


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
Build Options: BUILD_NATIVE, OPTIONAL_API
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

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

Directories
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/asterisk.pid
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


Advertisements

Kamailio Transaction management

Kamailio is basically only a transaction stateful proxy, without any dialog support build in. Here the TM module enables stateful processing of SIP transactions. State is a requirement for many complex logic such as accounting, forking , DNS resolution .

Branches – A single SIP INVITE request may be forked to multiple destinations , all of which together is called destination sets and Individual elements within the destination sets are called branches. A transaction can have more than one branch.
For example, during DNA failover, each failed DNS SRV destination can introduce a new branch.

Serial, Parallel and Combined Forking – By default kamailio performs parallel forking sending msg to all destinations and waiting for response , however it can also do serial ie send request one by one and wait for response /timeout before sending next . By use of priorities ( q valaue 0 – 1.0) , Kamailio can also intermix the forking technique ie describing priority oder for serial and same level for parallel . The destination uri are loaded using unctions t_load_contacts() and t_next_contacts().

parallel forking exmaple

request_route {
  seturi("sip:a@example.com");
  append_branch("sip:b@example.com");
  append_branch("sip:c@example.com");
  append_branch("sip:d@example.com");

  t_relay();
  break;
}

mixed forking exmaple

modparam("tm", "contacts_avp", "tm_contacts");
modparam("tm", "contact_flows_avp", "tm_contact_flows");

request_route {
  seturi("sip:a@example.com"); // lowest 0 
  append_branch("sip:b@example.com", "0.5"); // shoudl be in parallel with C
  append_branch("sip:c@example.com", "0.5"); // shoudl be in parallel with B
  append_branch("sip:d@example.com", "1.0"); // highest priority , should be tried first

  t_load_contacts();   // load all branches as per q values, store them in AVP configured in modparam 
  t_next_contacts();   // takes AVP and extracts higher q value branch

  t_relay();
  break;
}

Code to terminate when no more branches are found ( -1 returned) and return the message upstream

failure_route["serial"]
{
  if (!t_next_contacts()) {
    exit;
  }
  t_on_failure("serial");
  t_relay();
}

TM Module

t_relay, t_relay_to_udp and t_relay_to_tcp are main functions to setup transaction state, absorb retransmissions from upstream, generate downstream retransmissions and correlate replies to requests.

Memeory

TM copies clones of received SIP messages in shared memory. non-TM functions operate over the received message in private memory. Therefore core operations ( like record_route) should ne called before settings the trasnaction state ( t_realy ) for statefully processing a message.

An INVITE transaction will be kept in memory for maximum: max_inv_lifetime + fr_timer + wt_timer.
While A non-INVITE transaction will be kept in memory for a maximum: max_noninv_lifetime + wt_timer.

Parameters :

various parameters are used to fine tune how trsnactions are handled and timedout in kamailio. Note all timers are set in miliseconds notation.

fr_timer (integer) – timer hit when no final reply for a request or ACK for a negative INVITE reply arrives. Default 30000 ms (30 seconds).

fr_inv_timer (integer) – timer hit when no final reply for an INVITE arrives after a provisional message was received on branch. Default 120000 ms (120 seconds).

restart_fr_on_each_reply (integer) – restart fr_inv_timer fir INVITE transaction for each provisional reply. Otherwise it will be sreatred only for fisrt and then increasing provisonal replies. Turn it off in cases when dealing with bad UAs that continuously retransmit 180s, not allowing the transaction to timeout.

max_inv_lifetime (integer) – Maximum time an INVITE transaction is allowed to be active in a tansaction. It starts from the time trnsaction was created and after this timer is hit , transaction is moved to either wait state or in the final response retransmission state. Default 180000 ms (180 seconds )

max_noninv_lifetime (integer) – Maximum time a non-INVITE transaction is allowed to be active. default 32000 ms (32 seconds )

wt_timer (integer) – Time for which a transaction stays in memory to absorb delayed messages after it completed.

delete_timer (integer) – Time after which a to-be-deleted transaction currently ref-ed by a process will be tried to be deleted again. This is now obsolte and now transaction is deleted the moment it’s not referenced anymore.

retr_timer1 (integer) – Initial retransmission period

retr_timer2 (integer) – Maximum retransmission period started increasingly from starts with retr_timer1 and stays constant after this

noisy_ctimer (integer) – if set, INVITE transactions that time-out (FR INV timer) will be always replied. Otherwise they will be quitely dropped without any 408 branch timeout resposne

auto_inv_100 (integer) – automatically send and 100 reply to INVITEs.

auto_inv_100_reason (string) – Set reason text of the automatically sent 100 to an INVITE.

unix_tx_timeout (integer) – nix socket transmission timeout,

aggregate_challenges (integer) – if more than one branch received a 401 or 407 as final response, then all the WWW-Authenticate and Proxy-Authenticate headers from all the 401 and 407 replies will be aggregated in a new final response.

blst_503 (integer) – reparse_invite=1.

blst_503_def_timeout (integer) – blacklist interval if no “Retry-After” header is present

blst_503_min_timeout / blst_503_max_timeout (integer) – minimum and maximun blacklist interval respectively

blst_methods_add (unsigned integer) – Bitmap of method types that trigger blacklisting on transaction timeouts and by default INVITE triggers blacklisting only

blst_methods_lookup (unsigned integer) – Bitmap of method types that are looked-up in the blacklist before being forwarded statefully. For default only applied to BYE.

reparse_invite (integer) – set if CANCEL and negative ACK requests are to be constructed from the INVITE message ( same record-set etc as INVITE ) which was sent out instead of building them from the received request.

ac_extra_hdrs (string) – Header fields prefixed by this parameter value are included in the CANCEL and negative ACK messages if they were present in the outgoing INVITE. Can be only used with reparse_invite=1.

reparse_on_dns_failover (integer) – SIP message after a DNS failover is constructed from the outgoing message buffer of the failed branch instead of from the received request.

on_sl_reply (string) – Sets reply route block, to which control is passed when a reply is received that has no associated transaction.

modparam("tm", "on_sl_reply", "stateless_replies")
...
onreply_route["stateless_replies"] {
    // return 0 if do not allow stateless replies to be forwarded
    return 1; // will pass to core for stateless forwading
}

xavp_contact (string) – name of XAVP storing the attributes per contact.

contacts_avp (string) – name of an XAVP that stores names of destination sets. Used by t_load_contacts() and t_next_contacts() for forking branches

contact_flows_avp (string) – name of an XAVP that were skipped

fr_timer_avp (string) – override teh value of fr_timer on per transactio basis , outdated

fr_inv_timer_avp (string) – same as abovel , outdated

cancel_b_method (integer) – method to CANCEL an unreplied transaction branch. Params :
0 will immediately stop the request (INVITE) retransmission on the branch so that unrpelied branches will be terminated
1 will keep retransmitting the request on unreplied branches.
2 end and retransmit CANCEL even on unreplied branches, stopping the request retransmissions.

unmatched_cancel (string) – sets how to forward CANCELs that do not match any transaction. Params :
0 statefully
1 statelessly
2 dropping them

ruri_matching (integer) – try to match the request URI when doing SIP 1.0 transaction matching as older SIP didnt have via cookies as in RFC 3261

via1_matching (integer) – match the topmost “Via” header when doing SIP 1.0 transaction matching

callid_matching (integer) – match the callid when doing transaction matching.

pass_provisional_replies (integer)

default_code (integer) – Default response code sent by t_reply() ( 500 )

default_reason (string) – Default SIP reason phrase sent by t_reply() ( “Server Internal Error” )

disable_6xx_block (integer)- treat all the 6xx replies like normal replies. However according to RFC receiving a 6xx will cancel all the running parallel branches, will stop DNS failover and forking.

local_ack_mode (integer) – where locally generated ACKs for 2xx replies to local transactions are sent. Params :
0 – the ACK destination is choosen according next hop in contact and the route set and then DNS resolution is used on it
1 – the ACK is sent to the same address as the corresponding INVITE branch
2 – the ACK is sent to the source of the 2xx reply.

failure_reply_mode (integer) – how branches are managed and replies are selected for failure_route handling. Params :
0 – all branches are kept
1 – all branches are discarded
2 – only the branches of previous leg of serial forking are discarded
3 – all previous branches are discarded
if you dont want to drop all branches then use t_drop_replies() to sleectively drop

faked_reply_prio (integer) – how branch selection is done.

local_cancel_reason (boolean) – add reason headers for CANCELs generated due to receiving a final reply.

e2e_cancel_reason (boolean) – add reason headers for CANCELs generated due to receiving a CANCEL

remap_503_500 (boolean) – conversion of 503 response code to 500. RFC requirnment.

failure_exec_mode (boolean) – Add local failed branches in timer to be considered for failure routing blocks.

dns_reuse_rcv_socket (boolean) – reuse of the receive socket for additional branches added by DNS failover.

event_callback (str) – function in the kemi configuration file (embedded scripting language such as Lua, Python, …) to be executed instead of event_route[tm:local-request] block. The function recives a string param with name of the event

modparam("tm", "event_callback", "ksr_tm_event")
...
function ksr_tm_event(evname)
    KSR.info("===== TM module triggered event: " .. evname .. "\n");
    return 1;
end

relay_100 (str) – whether or not a SIP 100 response is proxied. not valid behavior when operating in stateful mode and only useful when in stateless mode

rich_redirect (int) – to add branch info in 3xx class reply. Params :
0 – no extra info is added (default)
1 – include branch flags as contact header parameter
2 – include path as contact uri Route header

Functions

These functions are operational blocks and route handlers for trsnactions handling in kamailio

t_relay([host, port]) – Relay a message statefully.
Exmaple to show if t_relay fails , atleast send a reply to UAC statelessly to not keep it waiting

if (!t_relay()) 
{ 
    sl_reply_error(); 
    break; 
};

t_relay_to_udp([ip, port]) / t_relay_to_tcp([ip, port]) – same as above but using specific protocol

if (some_conditon)
    t_relay_to_udp("1.2.3.4", "5060"); # sent to 1.2.3.4:5060 over udp
else
    t_relay_to_tcp(); # relay to msg. uri, but over tcp

t_relay_to_tls([ip, port])

t_relay_to_sctp([ip, port])

t_on_failure(failure_route) – on route block for failure management on a branch when a negative reply is recived to transaction. here uri is reset to value which it had on relaying.

t_on_branch_failure(branch_failure_route) – controls when negative response come for a transacion. here uri is reset to value which it had on relaying.

t_on_reply(onreply_route) – gets control when a reply from transaction is received

t_on_branch(branch_route) – control is passed after forking (when a new branch is created)

t_newtran() – Creates a new transaction

t_reply(code, reason_phrase) – Sends a stateful reply after a transaction has been established.

t_send_reply(code, reason)

t_lookup_request() – Checks if a transaction exists

t_retransmit_reply()

t_release() – Remove transaction from memory

t_forward_nonack([ip, port]) – forward a non-ACK request statefully

t_forward_nonack_udp(ip, port) / t_forward_nonack_tcp(ip, port)

t_forward_nonack_tls(ip, port)

t_forward_nonack_sctp(ip, port)

t_set_fr(fr_inv_timeout [, fr_timeout]) – Sets the fr_inv_timeout

t_reset_fr()

t_set_max_lifetime(inv_lifetime, noninv_lifetime) – Sets the maximum lifetime for the current INVITE or non-INVITE transaction, or for transactions created during the same script invocation

t_reset_max_lifetime()

t_set_retr(retr_t1_interval, retr_t2_interval) – Sets the retr_t1_interval and retr_t2_interval for the current transaction

t_reset_retr()

t_set_auto_inv_100(0|1) – switch automatically sending 100 replies to INVITEs on/off on a per transaction basis

t_branch_timeout() – Returns true if the failure route is executed for a branch that did timeout.

t_branch_replied()

t_any_timeout()

t_any_replied()

t_grep_status(“code”)

t_is_canceled()

t_is_expired()

t_relay_cancel()

t_lookup_cancel([1])
t_drop_replies([mode])
t_save_lumps()
t_load_contacts()
t_next_contacts()
t_next_contact_flow()
t_check_status(re)

t_check_trans() – check if a message belongs or is related to a transaction.

t_set_disable_6xx(0|1)
t_set_disable_failover(0|1)
t_set_disable_internal_reply(0|1)

t_replicate([params]) – Replicate the SIP request to a specific address.

t_relay_to(proxy, flags) – KSR.tm.t_relay()

t_set_no_e2e_cancel_reason(0|1)

t_is_set(target) – KEMI – KSR.tm.t_is_set() Return true if the attribute specified by ‘target’ is set for transaction. Target can be branch_route , failure_route and onreply_route

if not(KSR.tm.t_is_set("branch_route")>0) then
    core.set_branch_route("ksr_branch_manage");
end
if not(KSR.tm.t_is_set("onreply_route")>0) then
    core.set_reply_route("ksr_onreply_manage");
end
if not(KSR.tm.t_is_set("failure_route")>0) and (req_method == "INVITE") then
   core.set_failure_route("ksr_failure_manage");
end

t_use_uac_headers()

t_is_retr_async_reply()

t_uac_send(method, ruri, nexthop, socket, headers, body)

t_get_status_code() – Return the status code for transaction or -1 in case of error or no status code was set.

raw RPC cmds

kamctl rpc tm.list

{  

   "jsonrpc":"2.0",
   "result":[  
      {  
         "cell":"0x7f0698d06488",
         "tindex":50969,
         "tlabel":163886326,
         "method":"INVITE",
         "from":"From: ;tag=dddab54e\r\n",
         "to":"To: \r\n",
         "callid":"Call-ID: NjkyYjJlNzJkNzQ1OTYyZjE2MDM2NjFlYWZkNjY4OWE\r\n",
         "cseq":"CSeq: 1",
         "uas_request":"yes",
         "tflags":65,
         "outgoings":2,
         "ref_count":1,
         "lifetime":29578635
      }
   ],
   "id":3922
}

kamctl rpc tm.stats

before call

{  
   "jsonrpc":"2.0",
   "result":{  
      "current":0,
      "waiting":0,
      "total":3,
      "total_local":0,
      "rpl_received":6,
      "rpl_generated":6,
      "rpl_sent":6,
      "6xx":0,
      "5xx":3,
      "4xx":0,
      "3xx":0,
      "2xx":0,
      "created":3,
      "freed":3,
      "delayed_free":0
   },
   "id":4119
}

during call

{  

   "jsonrpc":"2.0",
   "result":{  
      "current":1,
      "waiting":0,
      "total":4,
      "total_local":0,
      "rpl_received":7,
      "rpl_generated":7,
      "rpl_sent":7,
      "6xx":0,
      "5xx":3,
      "4xx":0,
      "3xx":0,
      "2xx":0,
      "created":4,
      "freed":3,
      "delayed_free":0
   },
   "id":4217
}

during call wait

{  
   "jsonrpc":"2.0",
   "result":{  
      "current":1,
      "waiting":1,
      "total":4,
      "total_local":0,
      "rpl_received":8,
      "rpl_generated":8,
      "rpl_sent":8,
      "6xx":0,
      "5xx":4,
      "4xx":0,
      "3xx":0,
      "2xx":0,
      "created":4,
      "freed":3,
      "delayed_free":0
   },
   "id":4275
}

after call is completed

{  
   "jsonrpc":"2.0",
   "result":{  
      "current":0,
      "waiting":0,
      "total":4,
      "total_local":0,
      "rpl_received":8,
      "rpl_generated":8,
      "rpl_sent":8,
      "6xx":0,
      "5xx":4,
      "4xx":0,
      "3xx":0,
      "2xx":0,
      "created":4,
      "freed":4,
      "delayed_free":0
   },
   "id":4333
}

Opensips

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.

Features

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 https://telecom.altanai.com/2013/07/13/sip-entities/

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.

Interfaces

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
OPTIONS , REGISTRAR ,SIGNALING , UAC_REGISTRANT
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 ) ,
DISPATCHER , DROUTING ( Dynamic Routing / LCR ) , EMERGENCY ,ENUM ,
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 )

SIP messaging related , COMPRESSION , DIVERSION , IDENTITY ,MAXFWD , MANGLER
PATH , SIPMSGOPS ( SIP operations ) , TOPOLOGY_HIDING ,
UAC , UAC_AUTH , UAC_REDIRECT
URI , SST ( SIP Session Timer support )

Presence Modules like PRESENCE , PRESENCE_CALLINFO , PRESENCE_DIALOGINFO, PRESENCE_MWI (for Message Waiting Indication ) , PRESENCE_XCAPDIFF (for XCAP-DIFF event) , PRESENCE_XML
PUA , PUA_BLA , PUA_DIALOGINFO , PUA_MI , PUA_USRLOC , PUA_XMPP
B2B_SCA ( Back-to-Back Shared Call ), RLS ( Resource List Server )
XCAP , XCAP_CLIENT

2. Scripting modules

Script helper modules such as JSON , CFGUTILS , EXEC , TEXTOPS , AVPOPS , REGEX, MATHOPS , BENCHMARK ,
CARRIERROUTE , GFLAGS (Global shared flags )
PYTHON , LUA ,PERL , MMGEOIP ( MaxMind GeoIP )

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 ,
GROUP , USERBLACKLIST , SPEEDDIAL ,PEERING ( Radius peering )

Data caching as DNS_CACHE , USRLOC ,SQL_CACHER

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

3. Database modules

For SQL – DB_BERKELEY , DB_CACHEDB , DB_FLATSTORE , DB_HTTP , DB_MYSQL , DB_ORACLE ,DB_PERLVDB , DB_POSTGRES , DB_SQLITE
DB_TEXT , DB_UNIXODBC , DB_VIRTUAL

For noSQL – CACHEDB_CASSANDRA ,CACHEDB_COUCHBASE ,CACHEDB_LOCAL ,CACHEDB_MEMCACHED , CACHEDB_MONGODB , CACHEDB_REDIS , CACHEDB_SQL

4. External Integration modules

OpenSIPS API as EVENT_DATAGRAM , EVENT_FLATSTORE ( Text/File backend for events ), EVENT_ROUTE ,EVENT_RABBITMQ
EVENT_VIRTUAL ( Aggregator of event backends failover & balancing), EVENT_XMLRPC
MI_DATAGRAM ( DATAGRAM unix and network support for Management Interface )
MI_FIFO , MI_HTTP , MI_JSON , MI_XMLRPC_NG
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 )
PROTO_HEP , PROTO_SCTP , PROTO_TCP, PROTO_TLS , PROTO_UDP , PROTO_WS , PROTO_WSS

How to Install and use Opensips on your VoIP platform

Install from git repo

git clone git@github.com:OpenSIPS/opensips.git opensips_head
install gcc
make all

Install from apt

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 049AD65B
echo "deb http://apt.opensips.org 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

Routes

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");
exit();
}
route(1);
}
route[1] {
forward();
}
  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 (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");
route(NATMANAGE);
}

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

route {
lookup("location");
t_on_branch("op3");
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
}
}
branch_route[op3] {
if(uri=~"1\.2\.3\.4") {
drop();
}
}
  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] {
route(NATMANAGE);
if (t_is_canceled()) {
exit;
}
}

or on failure relay to voice mail

route {
lookup("location");
t_on_failure("op1");
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
}
}
failure_route[op1] {
if(is_method("INVITE")) {
t_relay("udp:voicemail.server.com:5060");
}
}
  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("sip:bob@opensips.org");  first branch
append_branch("sip:alice@opensips.org");  second branch
t_on_reply("global");
t_on_branch("1");
t_relay();
}

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

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

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")
t_on_reply("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
$(err.info) - 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=$(err.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");
exit;
}
  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=~"@foreign.com") {
append_hf("P-hint: foreign request\r\n");
exit;
}
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==127.0.0.1) {
log("message received on loopback interface\n");
};

dst_port – local port where the SIP packet was received

if(dst_port==5061)
{
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=~".*@opensips.org")
{
log("the caller is from opensips.org\n");
};

method – SIP method of the message.

if(method=="REGISTER")
{
log("this SIP request is a REGISTER message\n");
};

msg:len – the size of the message

if(msg:len&amp;amp;amp;amp;amp;gt;2048)
{
sl_send_reply("413", "message too large");
exit;
};

$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 {
route(1);
if($retcode==1)
{
log("The request is an INVITE\n");
};
}

route[1] {
if(is_method("INVITE"))
return(1);
return(2);
}

proto – transport protocol of the SIP message.

if(proto==UDP)
{
log("SIP message received over UDP\n");
};

status – status code of the reply.

if(status=="200")
{
log("this is a 200 OK reply\n");
};

1.10 src_ip – source IP address

if(src_ip==127.0.0.1)
{
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).

if(src_port==5061)
{
log("message sent from port 5061\n");
}

1.12 to_uri – URI from To header.

if(to_uri=~"sip:.+@opensips.org")
{
log("this is a request for opensips.org users\n");
};

1.13 uri – request URI.

if(uri=~"sip:.+@opensips.org")
{
log("this is a request for opensips.org 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.

if(msg:len&amp;amp;amp;amp;amp;gt;max_len)
{
sl_send_reply("413", "message too large to be forwarded over UDP without fragmentation");
exit;
}

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

alias=udp:company.tel.com:5060
alias=tcp:company.tel.com:5060

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
auto_aliases=0

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.

chroot=/other/diffroot

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”

db_version_table=”version_1_8″

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

db_default_url=”mysql://opensips:opensipsrw@localhost/opensips”

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 ]

db_max_async_connections=220


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.

disable_dns_failover=yes

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

dns_retr_time=3

3.25 dns_retr_no – Number of dns retransmissions before giving up.

dns_retr_no=3

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.

dns_servers_no=2

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’.

dns_try_ipv6=yes

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’.

dns_try_naptr=no

3.29 dns_use_search_list

dns_use_search_list=no

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 , 192.168.2.200 , 5060 , “” ),( any , 192.168.2.201 , 0 , “” )}

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

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

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

Each rule is defined by:

protocol : TCP, UDP, TLS or “any” for anything
port : number or 0 for any
ip/mask
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 11.22.33.44:5060”
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:10.10.10.10:5064
listen = ws:127.0.0.1:5060 use_children 5
listen = sctp:127.0.0.1:5060 as 99.88.44.33:5060 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.

log_facility=LOG_LOCAL0

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].

log_name=”osips-5070″

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.

max_while_loops=200

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.

maxbuffer=65536

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)

memdump=2

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)

memlog=2

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

mcast_loopback=yes

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

mcast_ttl=32

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.

mhomed=1

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 "mysql.so"<br> loadmodule "uri.so"<br> loadmodule "uri_db.so"<br> loadmodule "sl.so"<br> loadmodule "tm.so"<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).

open_files_limit=2048

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.

poll_method=select

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

reply_to_via=0

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.

query_buffer_size=5

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.

query_flush_time=10

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.

sip_warning=0

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.

tcp_children=4

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

tos=IPTOS_LOWDELAY<br> tos=0x10<br> tos=IPTOS_RELIABILITY

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.

 wdir="/usr/local/opensips" 

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

Routes

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");
exit();
}
route(1);
}
route[1] {
forward();
}
  • 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 (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
branch_route[MANAGE_BRANCH] {
xdbg("new branch [$T_branch_idx] to $ru\n");
route(NATMANAGE);
}

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

route {
lookup("location");
t_on_branch("op3");
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
}
}
branch_route[op3] {
if(uri=~"1\.2\.3\.4") {
drop();
}
}
  • 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] {
route(NATMANAGE);
if (t_is_canceled()) {
exit;
}
}

or on failure relay to voice mail

route {
lookup("location");
t_on_failure("op1");
if(!t_relay()) {
sl_send_reply("500", "relaying failed");
}
}
failure_route[op1] {
if(is_method("INVITE")) {
t_relay("udp:voicemail.server.com:5060");
}
}
  • 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("sip:bob@opensips.org");  first branch
append_branch("sip:alice@opensips.org");  second branch
t_on_reply("global");
t_on_branch("1");
t_relay();
}

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

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

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")
t_on_reply("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
$(err.info) - 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=$(err.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");
exit;
}
  • 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=~"@foreign.com") {
append_hf("P-hint: foreign request\r\n");
exit;
}
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.)
(app_mono),
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.

//loading 
loadmodule "app_lua.so"
//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 KSR.tm.t_on_branch(…)

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

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

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 KSR.tm.t_on_branch_failure(…)

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()
    KSR.info("===== request - from kamailio lua script\n");
    if KSR.maxfwd.process_maxfwd(10) < 0 then
        KSR.sl.send_reply(483, "Too Many Hops");
        return;
    end
    //KSR.sl.sreply(200, "OK Lua");
    KSR.pv.sets("$du", "sip:127.0.0.1:5080")
    KSR.tm.t_on_branch("ksr_branch_route_one");
    KSR.tm.t_on_reply("ksr_onreply_route_one");
    KSR.tm.t_on_failure("ksr_failure_route_one");
    if KSR.tm.t_relay() < 0 then
        KSR.sl.send_reply(500, "Server error")
    end
end

function ksr_reply_route()
    KSR.info("===== response - from kamailio lua script\n");
end

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

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

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

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 KSR.info(…) : info log

KSR.info("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:
I – INVITE
A – ACK
B – BYE
C – CANCEL
R – REGISTER
M – MESSAGE
O – OPTIONS
S – SUBSCRIBE
P – PUBLISH
N – NOTIFY
U – UPDATE
K – KDMQ
G – GET
T – POST
V – PUT
D – DELETE

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

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_REGISTER() : true if REGISTER.

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:127.0.0.1:5060") then
  ...
end

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.seturi("sip:alice@voip.com");

KSR.setuser(…)

KSR.setuser("alice");

KSR.sethost(…)

KSR.sethost("voip.com");

KSR.setdsturi(…)

KSR.setdsturi("sip:voip.com:5061;transport=tls");

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.forward_uri("sip:127.0.0.1:5080;transport=tcp");

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.remove("X-My-Hdr");

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.unset("$avp(x)");

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.

Acc

KSR.acc.acc_db_request()

KSR.acc.acc_log_request()

KSR.acc.acc_request()

app_lua

executing Lua scripts from config file.

KSR.app_lua.dofile()

KSR.app_lua.dostring()

KSR.app_lua.run()

KSR.app_lua.run_p1()

KSR.app_lua.run_p2()

KSR.app_lua.run_p3()

KSR.app_lua.runstring()

Async

asynchronous operations for handling SIP requests

KSR.async.route()

KSR.async.task_route()

auth

KSR.auth.auth_challenge()

KSR.auth.consume_credentials()

KSR.auth.has_credentials()

KSR.auth.pv_auth_check()

auth_db

KSR.auth_db.auth_check()

KSR.auth_db.is_subscriber()

-tbd –

Ref :

Secure Communication with RTP, SRTP , ZRTP and DTLS

With advent of Voice over IP , the real time streaming of data/audio/video also became critically important to be protected from eavesdropping or modification over the open internet.

While Secure Real-time Transport Protocol (SRTP) is a profile of the Real-time Transport Protocol (RTP), which can provide confidentiality, message authentication, and replay protection to the RTP traffic and to the control traffic for RTP, the Real-time Transport Control Protocol (RTCP).

ZRTP is a protocol that negotiates the keys and other information required to setup a SRTP audio and video session

DTLS keying happens on the media path, independent of any out-of-band signalling channel present.

SRTP provides a framework for encryption and message authentication of RTP and RTCP streams by negotiating keys. It defines a set of default cryptographic transforms and it allows new transforms to be introduced in the future. SRTCP securely provides the same features to RTCP, as the ones provided by SRTP to RTP.

Jitsi Client SRTP configuration

An offer can include any of –

  • plain RTP (RTP/AVP),
  • RTP with RTCP-based feedback (RTP/AVPF),
  • Secure RTP (RTP/SAVP), or
  • Secure RTP with RTCP-based feedback (RTP/SAVPF)

SDP for RTP/AVP

v=0
o=987654321-jitsi.org 0 0 IN IP4 x.x.x.x.
s=-
c=IN IP4 x.x.x.x
t=0 0
m=audio 24380 RTP/AVP 9
a=rtcp-xr:voip-metrics
a=rtpmap:9 G722/8000
a=sendrecv
m=audio 24400 RTP/AVP 9
a=rtcp-xr:voip-metrics
a=rtpmap:9 G722/8000
a=sendrecv

or

v=0.
o=987654321-jitsi.org 0 0 IN IP4 x.x.x.x.
s=-.
c=IN IP4 x.x.x.x.
t=0 0.
m=audio 5018 UDP/TLS/RTP/SAVP 9.
a=rtpmap:9 G722/8000.
a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level.
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level.
a=rtcp-xr:voip-metrics.
a=setup:actpass.
a=fingerprint:sha-1 B9:0F:89:EE:BD:1F:B1:C4:86:B6:D7:5C:25:88:53:F4:02:F4:F5:91.
m=audio 5018 RTP/SAVPF 9.
a=rtpmap:9 G722/8000.
a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level.
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level.
a=rtcp-xr:voip-metrics.
a=setup:actpass.
a=fingerprint:sha-1 B9:0F:89:EE:BD:1F:B1:C4:86:B6:D7:5C:25:88:53:F4:02:F4:F5:91.

The m line indicates which mode of RTP and RTCP is it offering .

Case where offerer/calleer wants to establish a Secure RTP audio stream on plain RTP with DTLS-SRTP as the key management protocol.

type: offer, sdp: 
v=0
o=- 2977074634695769063 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=msid-semantic: WMS i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:w5/T
a=ice-pwd:zuPM49QcEX3cKRQiKylJU4Y6
a=ice-options:trickle
a=fingerprint:sha-256 5A:70:05:55:C1:5A:82:51:02:D3:00:A3:BF:E7:EF:62:DF:29:EB:F2:9F:5F:51:58:12:D9:4C:AA:41:36:86:13
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO 5ffdb0f9-48b1-43bc-9f63-ea032643aeba
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:2215726670 cname:e6egqLfRbLu6vH45
a=ssrc:2215726670 msid:i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO 5ffdb0f9-48b1-43bc-9f63-ea032643aeba
a=ssrc:2215726670 mslabel:i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO
a=ssrc:2215726670 label:5ffdb0f9-48b1-43bc-9f63-ea032643aeba
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:w5/T
a=ice-pwd:zuPM49QcEX3cKRQiKylJU4Y6
a=ice-options:trickle
a=fingerprint:sha-256 5A:70:05:55:C1:5A:82:51:02:D3:00:A3:BF:E7:EF:62:DF:29:EB:F2:9F:5F:51:58:12:D9:4C:AA:41:36:86:13
a=setup:actpass
a=mid:2
a=sctpmap:5000 webrtc-datachannel 1024

SRTP on kamailio

For Secure Communication kamailio supports – 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.

Code to set flag rtp_secure_media to true if both TLS and SRTP are active

<condition field="${rtp_has_crypto}" expression="^(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)$" break="never">	<action application="set" data="rtp_secure_media=true"/></condition>

Invite from Jitsi client alternatively offering 3 different types of audio SDP’s – RTP/SAVPF , RTP/SAVP and RTP/AVP. Which ever will be accepted by the other endpoint will be communicated back using SDP in 200 OK.

INVITE sip:99999999999@x.x.x.x:5080 SIP/2.0
   Call-ID: 2a34d1e981602c82c345513f3f2f89ed@0:0:0:0:0:0:0:0
   CSeq: 1 INVITE
   From: "altanai" ;tag=bed49270
   To: 
   Via: SIP/2.0/UDP y.y.y.y:5060;branch=z9hG4bK-3130-9657d2ae9b662779bc08cdd32881828f
   Max-Forwards: 70
   Contact: "altanai" 
   User-Agent: Jitsi2.10.5550Mac OS X
   Content-Type: application/sdp
   Content-Length: 2336
   v=0
   o=7777777777-jitsi.org 0 0 IN IP4 y.y.y.y
   s=-
   c=IN IP4 y.y.y.y
   t=0 0
   m=audio 5016 UDP/TLS/RTP/SAVP 9
   a=rtpmap:9 G722/8000
   a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
   a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
   a=rtcp-xr:voip-metrics
   a=setup:actpass
   a=fingerprint:sha-1 55:CF:25:5D:D5:65:71:C8:D9:FF:97:AD:CC:F2:08:DB:38:DD:81:38
m=audio 5016 RTP/SAVPF 9
   a=rtpmap:9 G722/8000
   a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
   a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
   a=rtcp-xr:voip-metrics
   a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:Ekb2qAA8F7VCmz0FMSrad0rIt8duHQFedu/KxMbD
   a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:rEeGiaLCUbFw0sS0FxARgX9i5pwEj/frxxbgGkch
   a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:up9VO2T/rfu8V0cecA4RuG0aWgSaCC5gD/p/RdY1odg1p/0Pto0=
   a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:6yLDM31gAuwrlL0qkH72QYJLwtzX1IX+Z+7UML3VA5CpIbUWeAw=
   a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:2Q3b3UpPJMosXTrm/0Ui5q3Mw8tQ6ig5Xq0jt4Ibj0t5hVQx5KBRbC+8sMJDMg==
   a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:yVs8C3xPFY2LAUXIH+dlgBBNSz+jm1cbAQlAgv8hPKGe1zfu2wzx1d465UfFzQ==
   a=crypto:7 F8_128_HMAC_SHA1_80 inline:bhIPhj1TryAB63p/g8B3gL5NXJJ7V4kbjXqYaU54
   a=setup:actpass
   a=fingerprint:sha-1 55:CF:25:5D:D5:65:71:C8:D9:FF:97:AD:CC:F2:08:DB:38:DD:81:38
m=audio 5016 RTP/SAVP 9
   a=rtpmap:9 G722/8000
   a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
   a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
   a=rtcp-xr:voip-metrics
   a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:Ekb2qAA8F7VCmz0FMSrad0rIt8duHQFedu/KxMbD
   a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:rEeGiaLCUbFw0sS0FxARgX9i5pwEj/frxxbgGkch
   a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:up9VO2T/rfu8V0cecA4RuG0aWgSaCC5gD/p/RdY1odg1p/0Pto0=
   a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:6yLDM31gAuwrlL0qkH72QYJLwtzX1IX+Z+7UML3VA5CpIbUWeAw=
   a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:2Q3b3UpPJMosXTrm/0Ui5q3Mw8tQ6ig5Xq0jt4Ibj0t5hVQx5KBRbC+8sMJDMg==
   a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:yVs8C3xPFY2LAUXIH+dlgBBNSz+jm1cbAQlAgv8hPKGe1zfu2wzx1d465UfFzQ==
   a=crypto:7 F8_128_HMAC_SHA1_80 inline:bhIPhj1TryAB63p/g8B3gL5NXJJ7V4kbjXqYaU54
m=audio 5016 RTP/AVP 9
a=rtpmap:9 G722/8000
a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=rtcp-xr:voip-metrics

Kamailio in secure mode selects the SRTP block of Audio SDP and responds in 200 OK

RTP to SRTP Bridging in Freeswitch

RTP to SRTP in Freeswitch

Enable ZRTP globally. Can override this on a per channel basis http://wiki.freeswitch.org/wiki/ZRTP (on how to enable zrtp)

When SRTP it’s critical to not offer or accept variable bit rate codecs, doing so would leak information and possibly compromising SRTP stream. (FS-6404)

Supported SRTP Crypto Suites:

AEAD_AES_256_GCM_8

This algorithm is identical to AEAD_AES_256_GCM (see Section 5.2 of [RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used. An AEAD_AES_256_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.

AEAD_AES_128_GCM_8

This algorithm is identical to AEAD_AES_128_GCM (see Section 5.1 of [RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used. An AEAD_AES_128_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.

AES_CM_256_HMAC_SHA1_80 | AES_CM_192_HMAC_SHA1_80 | AES_CM_128_HMAC_SHA1_80

AES_CM_128_HMAC_SHA1_80 is the SRTP default AES Counter Mode cipher and HMAC-SHA1 message authentication with an 80-bit authentication
tag. The master-key length is 128 bits and has a default lifetime of a maximum of 2^48 SRTP packets or 2^31 SRTCP packets, whichever comes
first.

AES_CM_256_HMAC_SHA1_32 | AES_CM_192_HMAC_SHA1_32 | AES_CM_128_HMAC_SHA1_32

This crypto-suite is identical to AES_CM_128_HMAC_SHA1_80 except that the authentication tag is 32 bits. The length of the base64-decoded key and salt value for this crypto-suite MUST be 30 octets i.e., 240 bits; otherwise, the crypto attribute is considered invalid.

AES_CM_128_NULL_AUTH

The SRTP default cipher (AES-128 Counter Mode), but to use no authentication method. This policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5 of [RFC3711].

SRTP variables that modify behaviors based on direction/leg:

rtp_secure_media

possible values:
mandatory – Accept/Offer SAVP negotiation ONLY
optional – Accept/Offer SAVP/AVP with SAVP preferred
forbidden – More useful for inbound to deny SAVP negotiation
false – implies forbidden
true – implies mandatory

default if not set is accept SAVP inbound if offered.

rtp_secure_media_inbound | rtp_secure_media_outbound

This is the same as rtp_secure_media, but would apply to either inbound
or outbound offers specifically.

How to specify crypto suites:

By default without specifying any crypto suites FreeSWITCH will offer crypto suites from strongest to weakest accepting the strongest each
endpoint has in common. If you wish to force specific crypto suites you can do so by appending the suites in a comma separated list in the order that you wish to offer them in.

Examples:
rtp_secure_media=mandatory:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=optional:AES_CM_256_HMAC_SHA1_80
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80

Additionally you can narrow this down on either inbound or outbound by specifying as so:

rtp_secure_media_inbound=true:AEAD_AES_256_GCM_8
rtp_secure_media_inbound=mandatory:AEAD_AES_256_GCM_8
rtp_secure_media_outbound=true:AEAD_AES_128_GCM_8
rtp_secure_media_outbound=optional:AEAD_AES_128_GCM_8

rtp_secure_media_suites

Optionaly you can use rtp_secure_media_suites to dictate the suite list and only use rtp_secure_media=[optional|mandatory|false|true] without having to dictate the suite list with the rtp_secure_media* variables.

In vars.xml

SIP and TLS settings. http://wiki.freeswitch.org/wiki/Tls valid options: sslv2,sslv3,sslv23,tlsv1,tlsv1.1,tlsv1.2 default: tlsv1,tlsv1.1,tlsv1.2

TLS cipher suite: default ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH The actual ciphers supported will change per platform. openssl ciphers -v ‘ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH’ Will show you what is available in your verion of openssl.

Logs :

A client at 7777777777@ is trying to call 9999999999@ , which freeswtch has to proxy and convert from RTP to SRTP.
The following debug logs form sofia external show this process.

recv 1215 bytes from udp/[]:4642 at 07:08:27.374857:


INVITE sip:9999999999@:5080;transport=UDP SIP/2.0
   Via: SIP/2.0/UDP :47851;branch=z9hG4bK-524287-1---7cc8ad9383e9787d;rport
   Max-Forwards: 70
   Contact: :47851;transport=UDP>
   To: :5080;transport=UDP>
   From: :5080;transport=UDP>;tag=5df9f82c
   Call-ID: lFNvnuABQfOpROxfFp-MZQ..
   CSeq: 1 INVITE
   Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE
   Content-Type: application/sdp
   User-Agent: Z 5.2.28 rv2.8.115
   Allow-Events: presence, kpml, talk
   Content-Length: 607
v=0
   o=Z 20472192 0 IN IP4 
   s=Z
   c=IN IP4 
   t=0 0
   m=audio 8000 RTP/AVP 106 9 3 111 0 8 97 110 112 98 101 100 99 102
   a=rtpmap:106 opus/48000/2
   a=fmtp:106 minptime=20; cbr=1; maxaveragebitrate=40000; useinbandfec=1
   a=rtpmap:111 speex/16000
   a=rtpmap:97 iLBC/8000
   a=fmtp:97 mode=20
   a=rtpmap:110 speex/8000
   a=rtpmap:112 speex/32000
   a=rtpmap:98 telephone-event/48000
   a=fmtp:98 0-16
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=rtpmap:100 telephone-event/16000
   a=fmtp:100 0-16
   a=rtpmap:99 telephone-event/32000
   a=fmtp:99 0-16
   a=rtpmap:102 G726-32/8000
   a=sendrecv

[NOTICE] switch_channel.c:1104 New Channel sofia/external/7777777777@:5080 [ed5e07ee-bd00-4a47-b4e1-6abc9dd23ed6]

[DEBUG] switch_core_state_machine.c:584 (sofia/external/7777777777@:5080) Running State Change CS_NEW (Cur 1 Tot 33)

[DEBUG] sofia.c:10078 sofia/external/7777777777@:5080 receiving invite from :4642 version: 1.9.0 -742-8f1be0 64bit

[DEBUG] sofia.c:7291 Channel sofia/external/7777777777@:5080 entering state [received][100]

[DEBUG] sofia.c:7301 Remote SDP:
v=0
o=Z 20472192 0 IN IP4 
s=Z
c=IN IP4 
t=0 0
m=audio 8000 RTP/AVP 106 9 3 111 0 8 97 110 112 98 101 100 99 102
a=rtpmap:106 opus/48000/2
a=fmtp:106 minptime=20; cbr=1; maxaveragebitrate=40000; useinbandfec=1
a=rtpmap:111 speex/16000
a=rtpmap:97 iLBC/8000
a=fmtp:97 mode=20
a=rtpmap:110 speex/8000
a=rtpmap:112 speex/32000
a=rtpmap:98 telephone-event/48000
a=fmtp:98 0-16
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=rtpmap:100 telephone-event/16000
a=fmtp:100 0-16
a=rtpmap:99 telephone-event/32000
a=fmtp:99 0-16
a=rtpmap:102 G726-32/8000
[DEBUG] sofia.c:7693 (sofia/external/7777777777@:5080) State Change CS_NEW -> CS_INIT
[DEBUG] switch_core_state_machine.c:603 (sofia/external/7777777777@:5080) State NEW
[DEBUG] switch_core_state_machine.c:584 (sofia/external/7777777777@:5080) Running State Change CS_INIT (Cur 1 Tot 33)
[DEBUG] switch_core_state_machine.c:627 (sofia/external/7777777777@:5080) State INIT
[DEBUG] mod_sofia.c:93 sofia/external/7777777777@:5080 SOFIA INIT
[DEBUG] switch_core_state_machine.c:40 sofia/external/7777777777@:5080 Standard INIT
[DEBUG] switch_core_state_machine.c:48 (sofia/external/7777777777@:5080) State Change CS_INIT -> CS_ROUTING
[DEBUG] switch_core_state_machine.c:627 (sofia/external/7777777777@:5080) State INIT going to sleep
[DEBUG] switch_core_state_machine.c:584 (sofia/external/7777777777@:5080) Running State Change CS_ROUTING (Cur 1 Tot 33)
[DEBUG] switch_channel.c:2249 (sofia/external/7777777777@:5080) Callstate Change DOWN -> RINGING
[DEBUG] switch_core_state_machine.c:643 (sofia/external/7777777777@:5080) State ROUTING
send 389 bytes to udp/[]:4642 at 07:08:27.376085:

SIP/2.0 100 Trying

   Via: SIP/2.0/UDP :47851;branch=z9hG4bK-524287-1---7cc8ad9383e9787d;rport=4642;received=
   From: :5080;transport=UDP>;tag=5df9f82c
   To: :5080;transport=UDP>
   Call-ID: lFNvnuABQfOpROxfFp-MZQ..
   CSeq: 1 INVITE
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Content-Length: 0

After the invote is recived and processed with 100 trying reply , the routing and rtp secure trabformation begins by adding crypto keys and forarding to

[DEBUG] mod_sofia.c:154 sofia/external/7777777777@:5080 SOFIA ROUTING
[DEBUG] switch_core_state_machine.c:236 sofia/external/7777777777@:5080 Standard ROUTING
[INFO] mod_dialplan_xml.c:637 Processing 7777777777 <7777777777>->9999999999 in context public
Dialplan: sofia/external/7777777777@:5080 Action set(rtp_secure_media=optional) 
Dialplan: sofia/external/7777777777@:5080 Action log(INFO Forwarding calls 9999999999@ )
Dialplan: sofia/external/7777777777@:5080 Action bridge(sofia/external/9999999999@)
[DEBUG] switch_core_state_machine.c:286 (sofia/external/7777777777@:5080) State Change CS_ROUTING -> CS_EXECUTE

[DEBUG] switch_core_state_machine.c:643 (sofia/external/7777777777@:5080) State ROUTING going to sleep

[DEBUG] switch_core_state_machine.c:584 (sofia/external/7777777777@:5080) Running State Change CS_EXECUTE (Cur 1 Tot 33)

[DEBUG] switch_core_state_machine.c:650 (sofia/external/7777777777@:5080) State EXECUTE

[DEBUG] mod_sofia.c:209 sofia/external/7777777777@:5080 SOFIA EXECUTE

[DEBUG] switch_core_state_machine.c:328 sofia/external/7777777777@:5080 Standard EXECUTE

ed5e07ee EXECUTE sofia/external/7777777777@:5080 set(rtp_secure_media=optional)

[DEBUG] mod_dptools.c:1593 SET sofia/external/7777777777@:5080 [rtp_secure_media]=[optional]

ed5e07ee EXECUTE sofia/external/7777777777@:5080 log(INFO  Forwarding calls   9999999999@ )

[INFO] mod_dptools.c:1787  Forwarding calls   9999999999@ 

…

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [1 AEAD_AES_256_GCM_8 inline:aHJ1yquBtm4Lzfi2oMpe6cV7IBEy3YgKxrJ3qjvLuRXSuZfHcV4VtVNwHDw]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [1 AEAD_AES_256_GCM_8 inline:qeJbqlSbnKBNew575hSZ3LX78o6GBsjgOrSMxzGH/zb1E7mkls1Mda93U9w]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [1 AEAD_AES_256_GCM_8 inline:VghMVsjWQwnOAAjBJ1NTB3jZgfpNV/Yu4poxkAPMqkC7C+fhPKApCJrWg3U]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [2 AEAD_AES_128_GCM_8 inline:7XNrjjwC/eOVnWlBSp74DfiIGAEYn/BN+latfA]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [2 AEAD_AES_128_GCM_8 inline:UQrFpy9Q7L5DI/ww4e5IAmwy7BxSw5yd/T0v0Q]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [2 AEAD_AES_128_GCM_8 inline:ZqkEPrUFHkaQ+7CROp52H/JO0MbrYWk/Eyl9lQ]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:PTGAm2KlbfuKtIUVGtXknKKzALAzfILZJuPOjfO9S07eWRE6FR0aMUvjuehJgw]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:ahHIB0o/dp3SliYWK9BkxM7TfzILwG0bjDn7JuvYi+puRkTM4mYvvsSmywLaYA]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:crAs8dPcWJkEEGj5nqTvFGl/TWpxxb86k+dX5gBXhh+q6DO2pEqWNkQmm55aLA]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [4 AES_CM_192_HMAC_SHA1_80 inline:SLBJWjgMdfiYX7TUwWQ9CmqUsILLJrpBIVjbfuQmpBIFLvvA/XU]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [4 AES_CM_192_HMAC_SHA1_80 fNazWgWwNRPjUKNHVqkz44]

2819d6c2 2019-03-19 07:08:27.375398 [DEBUG] switch_core_media.c:1204 Set Local text crypto Key [4 AES_CM_192_HMAC_SHA1_80 inline:hbe9qqETBSK5hRQ8DI9mXL4QAjjGSR8tGDiTHCJF3yxCrRk1ajk]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:8q8mer9N2V4qVxnaazuJeT0KXgW2scONy36J3KaS]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:TP5NQ1yB8ZSCCwZMgXur9VHZ5SlpNfnXePj7eZrk]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:HT3F3iYG8H/majhBZbOs2Z8ye/WEVGT5Oytx2oQS]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:fEohh92lX2xLmeFYlt8YouM2jN4z5pU05d90BYfoAKU6m4CWv8g8AnifDUKk9A]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:+uBNmLcvj41hXoMxNlMNBpq68gU4PmLwYcdopEB/X/jfPElkUgHfguPIgIFJUg]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:cqk7D3+KMQ+31R4FFDRRzn/aluyIgjxBL59vfxcsdf5OW9izEJtU+06GewJyIA]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:Tv25TfP9fQZ+ljs/tFlHohkckiK4F6cemzEjHSvo2+q6No4ai+o]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:CY/Dizd1QrlobZtgnigr0hWE+oDSx4S1F51Zpo4aZamN+8ZMdp8]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:aEox/7IMps5c+uOWbosZ618+opkJV/GnrKc2EnAhVnDNeo91+No]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:0LwKGyljIed0zhukiMMyD5ive0ZsyybwBrnevcAv]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:eZN8rAG8UPPntdYxsg1kkWL4qMsVgTiGGiS4UeUM]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:bAYzbfr+El8usaTkPBR6iFuTda4uLNGjyx9lQWkX]

[DEBUG] switch_core_media.c:1204 Set Local audio crypto Key [9 AES_CM_128_NULL_AUTH inline:5m3142gGG1HZ5VnoXsAOyopSwDCYbrIsGpdbEO3D]

[DEBUG] switch_core_media.c:1204 Set Local video crypto Key [9 AES_CM_128_NULL_AUTH inline:zXk67wjwRhSilq0kiz5TWxXqrxuTaWTA3qqbVo/G]

[DEBUG] switch_core_media.c:1204 Set Local text crypto Key [9 AES_CM_128_NULL_AUTH inline:FRP9CJbBO+PRj6I9RSBAiMxRZ/qFtyrEXPfxocG0]

[DEBUG] sofia_glue.c:1299 sofia/external/9999999999@ sending invite version: 1.9.0 -742-8f1b7e0 64bit

Local SDP:

v=0
o=FreeSWITCH 1552960557 1552960558 IN IP4 
s=FreeSWITCH
c=IN IP4 
t=0 0
m=audio 18750 RTP/SAVP 102 9 0 8 103 101
a=rtpmap:102 opus/48000/2
a=fmtp:102 useinbandfec=1; maxaveragebitrate=30000; maxplaybackrate=48000; ptime=20; minptime=10; maxptime=40; stereo=1
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:103 telephone-event/48000
a=fmtp:103 0-16
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=crypto:1 AEAD_AES_256_GCM_8 inline:aHJ1yquBtm4Lzfi2oMpe6cV7IBEy3YgKxrJ3qjvLuRXSuZfHcV4VtVNwHDw
a=crypto:2 AEAD_AES_128_GCM_8 inline:7XNrjjwC/eOVnWlBSp74DfiIGAEYn/BN+latfA
a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:PTGAm2KlbfuKtIUVGtXknKKzALAzfILZJuPOjfO9S07eWRE6FR0aMUvjuehJgw
a=crypto:4 AES_CM_192_HMAC_SHA1_80 inline:SLBJWjgMdfiYX7TUwWQ9CmqUsILLJrpBIVjbfuQmpBIFLvvA/XU
a=crypto:5 AES_CM_128_HMAC_SHA1_80 inline:8q8mer9N2V4qVxnaazuJeT0KXgW2scONy36J3KaS
a=crypto:6 AES_CM_256_HMAC_SHA1_32 inline:fEohh92lX2xLmeFYlt8YouM2jN4z5pU05d90BYfoAKU6m4CWv8g8AnifDUKk9A
a=crypto:7 AES_CM_192_HMAC_SHA1_32 inline:Tv25TfP9fQZ+ljs/tFlHohkckiK4F6cemzEjHSvo2+q6No4ai+o
a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:0LwKGyljIed0zhukiMMyD5ive0ZsyybwBrnevcAv
a=crypto:9 AES_CM_128_NULL_AUTH inline:5m3142gGG1HZ5VnoXsAOyopSwDCYbrIsGpdbEO3D
a=ptime:20
a=sendrecv

Once the SDP is ready with crypto keys it is the forwarded to the next_up

send 2104 bytes to udp/[]:5060 at 07:08:27.378167:


INVITE sip:9999999999@ SIP/2.0
   Via: SIP/2.0/UDP :5080;rport;branch=z9hG4bKmF251mK2pN35B
   Max-Forwards: 69
   From: "7777777777" >;tag=vcKeKD6SN02cB
   To: >
   Call-ID: a27898fd-c4b8-1237-ddaa-02a933b32da0
   CSeq: 1935861 INVITE
   Contact: :5080>
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
   Supported: timer, path, replaces
   Allow-Events: talk, hold, conference, refer
   Content-Type: application/sdp
   Content-Disposition: session
   Content-Length: 1304
   X-FS-Support: update_display,send_info
   Remote-Party-ID: "7777777777" >;party=calling;screen=yes;privacy=off
v=0
   o=FreeSWITCH 1552960557 1552960558 IN IP4 
   s=FreeSWITCH
   c=IN IP4 
   t=0 0
   m=audio 18750 RTP/SAVP 102 9 0 8 103 101
   a=rtpmap:102 opus/48000/2
   a=fmtp:102 useinbandfec=1; maxaveragebitrate=30000; maxplaybackrate=48000; ptime=20; minptime=10; maxptime=40; stereo=1
   a=rtpmap:9 G722/8000
   a=rtpmap:0 PCMU/8000
   a=rtpmap:8 PCMA/8000
   a=rtpmap:103 telephone-event/48000
   a=fmtp:103 0-16
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=crypto:1 AEAD_AES_256_GCM_8 inline:aHJ1yquBtm4Lzfi2oMpe6cV7IBEy3YgKxrJ3qjvLuRXSuZfHcV4VtVNwHDw
   a=crypto:2 AEAD_AES_128_GCM_8 inline:7XNrjjwC/eOVnWlBSp74DfiIGAEYn/BN+latfA
   a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:PTGAm2KlbfuKtIUVGtXknKKzALAzfILZJuPOjfO9S07eWRE6FR0aMUvjuehJgw
   a=crypto:4 AES_CM_192_HMAC_SHA1_80 inline:SLBJWjgMdfiYX7TUwWQ9CmqUsILLJrpBIVjbfuQmpBIFLvvA/XU
   a=crypto:5 AES_CM_128_HMAC_SHA1_80 inline:8q8mer9N2V4qVxnaazuJeT0KXgW2scONy36J3KaS
   a=crypto:6 AES_CM_256_HMAC_SHA1_32 inline:fEohh92lX2xLmeFYlt8YouM2jN4z5pU05d90BYfoAKU6m4CWv8g8AnifDUKk9A
   a=crypto:7 AES_CM_192_HMAC_SHA1_32 inline:Tv25TfP9fQZ+ljs/tFlHohkckiK4F6cemzEjHSvo2+q6No4ai+o
   a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:0LwKGyljIed0zhukiMMyD5ive0ZsyybwBrnevcAv
   a=crypto:9 AES_CM_128_NULL_AUTH inline:5m3142gGG1HZ5VnoXsAOyopSwDCYbrIsGpdbEO3D
   a=ptime:20

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

Primarily 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

loadmodule topoh.so
modparam("topoh", "mask_key", "YouDoHaveToChangeThisKey")
modparam("topoh", "mask_ip", "10.0.0.1")
modparam("topoh", "mask_callid", 1)

Params

mask_key (str)
mask_ip (str)
mask_callid (integer)
uparam_name (str)
uparam_prefix (str)
vparam_name (str)
vparam_prefix (str)
callid_prefix (str)
sanity_checks (integer)
uri_prefix_checks (integer)
event_callback (str)

Primarily tis module uses mask key to code the trimmed via header information and insert them into pre specified param names with prefixes. Hence it can work with stageful or stateless proxy and can also work if server is restarted in between

topos module

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

It requires 2 modules rr module since server must perform record routing to ensure in-dialog requests are encoded/decoded and database module to store the data for topology stripping and restoring.

Params :
storage (str) – could be redis or database backend

modparam("topos", "storage", "redis")

db_url (str)

modparam("topos", "db_url", "dbdriver://username:password@dbhost/dbname") 
modparam("topos", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio”

mask_callid (int) – Whether to replace or not the Call-ID with another unique id generated by Kamailio. ( present with topoh)
sanity_checks (int) – with sanity module to perform checks before encoding /decoding
branch_expire (int)
dialog_expire (int)
clean_interval (int)
event_callback (str) – callback event

modparam("topos", "event_callback", "ksr_topos_event")
..
function ksr_topos_event(evname)
 KSR.info("===== topos module triggered event: " .. evname .. "\n");
 return 1;
end

event route :
event_route[topos:msg-outgoing]

loadmodule "topos.so"
loadmodule "topos_redis.so"

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

FireWall

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

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
: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 INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -j SERVICES 
-A OUTPUT -o lo -j ACCEPT 
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -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-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -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 PRIVATE -d 192.168.0.0/16 -j DROP 
-A PRIVATE -d 172.16.0.0/12 -j DROP 
-A PRIVATE -d 10.0.0.0/8 -j DROP 
-A PRIVATE -j RETURN 
-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 tcp -j CHECK_TCP 
-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 
COMMIT

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

server_signature=no

and

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.so"

// 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");
    exit;
  }
  ...
}

Fail2Ban

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

Opensips as SIP gateway

OpenSIP provided dispatcher modules which computes hashes over parts of the request and selects an address from a destination set which is then as outbound proxy.

In the config of opensips load the file dispatcher.list with destination sets

modparam("dispatcher", "list_file", "/var/run/opensips/dispatcher.list")
 proxies
 2 sip:127.0.0.1:5080
 2 sip:127.0.0.1:5082
 gateways
 1 sip:127.0.0.1:7070
 1 sip:127.0.0.1:7072
 1 sip:127.0.0.1:7074

or one can also load the sets from the database

modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database")

Tthe algorithm used to select the destination address.
“0” – hash over callid
“1” – hash over from uri.
“2” – hash over to uri.
“3” – hash over request-uri.
“4” – round-robin (next destination).
“5” – hash over authorization-username (Proxy-Authorization or “normal” authorization). If no username is found, round robin is used.
“6” – random (using rand()).
“7” – hash over the content of PVs string. Note: This works only when the parameter hash_pvar is set.
“X” – if the algorithm is not implemented, the first entry in set is chosen.

and the state of the destination address can be

“a”: active
“i”: inactive
“p”: probing

Load Balancer

Opensip can function as load balancer , distributing the load between different SIP Application servers .

example of gateway sets file in dbtext/diapatcher.list

id(int,auto) setid(int) destination(string) socket(string,null) state(int) weight(int) priority(int) attrs(string) description(string)
1:1:sip\:10.20.30.40\:5060:null:0:1:1:'carrier':'load balancer for OB'
2:2:sip\:10.50.60.70\:5060:null:0:1:1:'carrier':'Load balancer for IB'

Health Monitoring

Probing and pinging features in Opensips can detect whether gateways are responding or not . Threshold and probing mode can fine tune the behaviour.

OpenSIPS config file

sample config file for dispatcher module

 debug=9            debug level (cmd line: -dddddddddd)
 fork=no
 log_stderror=yes  (cmd line: -E)
 children=2
 check_via=no      (cmd. line: -v)
 dns=off           (cmd. line: -r)
 rev_dns=off       (cmd. line: -R)
 port=5060
 
mpath="/usr/local/lib/opensips/modules/"
loadmodule "maxfwd.so"
loadmodule "sl.so"
loadmodule "dispatcher.so"

—————– setting module-specific parameters —————

dispatcher params

 modparam("dispatcher", "list_file", "../etc/dispatcher.list")
 // modparam("dispatcher", "force_dst", 1)
 route{
 if ( !mf_process_maxfwd_header("10") )
 {
 sl_send_reply("483","To Many Hops");
 drop();
 };
 ds_select_dst("2", "0");
 forward();
 // t_relay();
 }
 

dbtext is an implementation for a simplified database engine based on text files. It can be used by OpenSIPS DB interface instead of other database module (like MySQL). It keeps everything in memory.

The db_text database system architecture contains

  • a database is represented by a directory in the local file system. NOTE: when you use db_text in OpenSIPS, the database URL for modules must be the path to the directory where the table-files are located, prefixed by “text://”,
    e.g., “text:///var/dbtext/opensips”.
  • a table is represented by a text file inside database directory.

Minimal OpenSIPS location db_text table definition

username(str) contact(str) expires(int) q(double) callid(str) cseq(int)

Minimal OpenSIPS subscriber db_text table example

username(str) password(str) ha1(str) domain(str) ha1b(str)
suser:supasswd:xxx:alpha.org:xxx

This database interface don’t support the data insertion with default values. All such values specified in the database
template are ignored.

db_mode (integer)

Set caching mode (0 – default) or non-caching mode (1). In caching mode, data is loaded at startup. In non-caching mode, the module check every time a table is requested whether the correspondingfile on disk has changed, and if yes, will re-load table from file.

Set db_mode parameter

modparam(“db_text”, “db_mode”, 1)

loadmodule "/path/to/opensips/modules/db_text.so"
modparam("module_name", "database_URL", "text:///path/to/dbtext/database
")

Subscriber and Location

Definition of ‘subscriber’ table (one line)

username(str) domain(str) password(str) first_name(str) last_name(str) phone(str) email_address(str) datetime_created(int) datetime_modified(int) confirmation(str) flag(str) sendnotification(str) greeting(str) ha1(str) ha1b(str) perms(str) allow_find(str) timezone(str,null) rpid(str,null)

Definition of ‘location’ and ‘aliases’ tables (one line)

username(str) domain(str,null) contact(str,null) received(str) expires(i
nt,null) q(double,null) callid(str,null) cseq(int,null) last_modified(st
r) flags(int) user_agent(str) socket(str)

Definition of ‘version’ table and sample records

table_name(str) table_version(int)
subscriber:3
location:6
aliases:6

Configuration file using dbtext databse for oersistant storage . Also using auth

debug_mode=yes
children=4

check_via=no    # (cmd. line: -v)
dns=no          # (cmd. line: -r)
rev_dns=no      # (cmd. line: -R)

listen=udp:10.100.100.1:5060

loadmodule "modules/dbtext/dbtext.so"

loadmodule "modules/sl/sl.so"
loadmodule "modules/tm/tm.so"
loadmodule "modules/rr/rr.so"
loadmodule "modules/maxfwd/maxfwd.so"
loadmodule "modules/usrloc/usrloc.so"
loadmodule "modules/registrar/registrar.so"
loadmodule "modules/textops/textops.so"
loadmodule "modules/textops/mi_fifo.so"

loadmodule "modules/auth/auth.so"
loadmodule "modules/auth_db/auth_db.so"

----------------- setting module-specific parameters ---------------

-- mi_fifo params --

modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")

-- usrloc params --

modparam("usrloc", "db_mode", 2)
modparam("usrloc|auth_db", "db_url", "text:///tmp/opensipsdb")

modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "user_column", "username")
modparam("auth_db", "domain_column", "domain")

route{
// initial sanity checks -- messages with max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};
if ($ml &amp;gt;=  65535 ) {
sl_send_reply("513", "Message too big");
exit;
};

// we record-route all messages -- to make sure that subsequent messages will go through this proxy;
if (!$rm=="REGISTER") record_route();
&lt;pre&gt;&lt;code&gt;// subsequent messages withing a dialog should take the path determined by record-routing
if (loose_route()) {
    // mark routing logic in request
    append_hf("P-hint: rr-enforced\r\n");
    route(1);
    exit;
};

if (!is_myself("$rd")) {
    // mark routing logic in request
    append_hf("P-hint: outbound\r\n");
    route(1);
    exit;
};

//if the request is for other domain use UsrLoc 
if (is_myself("$rd")) {
    if ($rm=="REGISTER") {
        # digest authentication
        if (!www_authorize("", "subscriber")) {
            www_challenge("", "0");
            exit;
        };

        save("location");
        exit;
    };

    lookup("aliases");
    if (!is_myself("$rd")) {
        append_hf("P-hint: outbound alias\r\n");
        route(1);
        exit;
    };

    # native SIP destinations are handled using our USRLOC DB
    if (!lookup("location")) {
        sl_send_reply("404", "Not Found");
        exit;
    };
};
append_hf("P-hint: usrloc applied\r\n");
route(1);&lt;/code&gt;&lt;/pre&gt;
}

route[1]
{
if (!t_relay()) {
sl_reply_error();
};
}

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 – http://www.brekeke.com/sip/ .

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 http://www.brekeke.com/sip/ and run the setup file .

brekeke0

brekeke01

brekeke1

brekeke8

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 127.0.0.1 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 http://www.brekeke.com/downloads/sip-server-trial-license.phpbrekeke12_001

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 Architecture , Core and Modules

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

Introduction to Kamailio and its role in telephony is covered here . This article just describes the structure of kamailio source code , core and its associated modules which define the behaviour of machine.

kamailio architecture

Core

The core includes:

memory manager
SIP message parser
locking system
DNS and transport layer management (UDP, TCP, TLS, SCTP)
configuration file parser and interpreter
stateless forwarding
pseudo-variables and transformations engines
RPC control interface API
timer API

The internal libraries include:

components from old Kamailio cores
database abstraction layers (DB API v1 and v2)
management interface (MI) API
statistics engine

Modules

there over 150 modules in kamailio delaing with various feature areas that can be catagorised as below

  • registrar and user location management
  • accounting, authorization and authentication
  • text and regular expression operations
  • stateless replying
  • stateful processing – SIP transaction management
  • SIP dialogs tracking – active calls management
  • instant messaging and presence extensions
  • RADIUS and LDAP support
  • SQL and no-SQL database connectors
  • MI and RPC transports
  • Enum, GeoIP API and CPL interpreter
  • topology hiding and NAT traversal
  • load balancing and least cost routing
  • asynchronous SIP request processing
  • interactive configuration file debugger
  • Lua, Perl, Python and Java SIP Servlet extensions

Locking Management

Kamailio provides a custom locking system its root element is a mutex semaphore, that can be set (locked) or unset (unlocked).
locking.h lib provides the functionality in C code.

Simple Locks API

gen_lock_t
lock_alloc(…)
lock_dealloc(…)
lock_init(…)
lock_destroy(…)
lock_get(…)
lock_try(…)
lock_release(…)

Lock Set API

gen_lock_set_t
lock_set_alloc(…)
lock_set_dealloc(…)
lock_set_init(…)
lock_set_destroy(…)
lock_set_get(…)
lock_set_release(…)

A problem however with locks is that processes can eat a lot of CPU. Locking issues also occur when locks are set but not unset resulting in no more SIP messages being processed. Hence Kamailio uses gdb with PID and get backtraces to the lock that wasnt released .

gdb /path/to/kamailio PID
gdb> bt

Memory Manager

Multliple processes run simultenously within kamailio server, hence it bears private and shared memeories to facailitate their working.
One can increase shared memory using -m and private memory using -M command line option.

Private Memory

Since this is specific per process, no synchronization is needed to access structures allocated in it, such as varaible not needed by pther process or ones for temporary operations. provate memory manager is accessed via mem/mem.h.

pkg_malloc(…)
pkg_free(…)
pkg_realloc(…)

Shared Memory

the data stored in shared memeory is visible in all Kamailio modules such as user location , TM structures for stateful processing, routing rules for the dispatcher etc. shared memeory can be acceses via mem/shm_mem.h. Here locks are used to prvent race conditions.

shm_malloc(…)
shm_free(…)
shm_realloc(…)

Problems in memory management can occur due to :
Out of memory by allocating memory at runtime and not freeing it afterwards , called memory leaks
writing more than allocated for that structure, called segmentation fault.

Data Structures

str
struct sip_uri
struct sip_msg
struct msg_start
struct hdr_field
struct to_body
struct via_body

SIP Parser

kamailio has an incremental parser. Lib file for SIP message parsing is parser/msg_parser.c with the corresponding header file parser/msg_parser.h.

parse_uri(…)
parse_msg(…)
parse_headers(…)
parse_to(…)


Since kamailio has a modular architecture with core components and modules to extend the functionality, this article will be discussing few of the essential modules in Kamailio. Specific modules Discussed in this Article :

  • UserLoc
  • Registrar
  • Dialog
  • UAC
  • XHTTP
  • Websocket

Few categories of modules discoverable via apt-cache search kamailio

  • kamailio – very fast and configurable SIP proxy
  • kamailio-autheph-modules – authentication using ephemeral credentials module for Kamailio
  • kamailio-berkeley-bin – Berkeley database module for Kamailio – helper program
  • kamailio-berkeley-modules – Berkeley database module for Kamailio
  • kamailio-carrierroute-modules – carrierroute module for Kamailio
  • kamailio-cnxcc-modules – cnxcc modules for Kamailio
  • kamailio-cpl-modules – CPL module (CPL interpreter engine) for Kamailio
  • kamailio-dbg – very fast and configurable SIP proxy [debug symbols]
  • kamailio-dnssec-modules – contains the dnssec module
  • kamailio-erlang-modules – earlang modules for Kamailio
  • kamailio-extra-modules – extra modules for Kamailio
  • kamailio-geoip-modules – contains the geoip module
  • kamailio-ims-modules – IMS module for Kamailio
  • kamailio-java-modules – contains the app_java module
  • kamailio-json-modules – Json parser and jsonrpc modules for Kamailio
  • kamailio-kazoo-modules – kazoo modules for Kamailio
  • kamailio-ldap-modules – LDAP modules for Kamailio
  • kamailio-lua-modules – contains the app_lua module
  • kamailio-memcached-modules – interface to memcached server
  • kamailio-mono-modules – contains the app_mono module
  • kamailio-mysql-modules – MySQL database connectivity module for Kamailio
  • kamailio-outbound-modules – Outbound module for Kamailio
  • kamailio-perl-modules – Perl extensions and database driver for Kamailio
  • kamailio-postgres-modules – PostgreSQL database connectivity module for Kamailio
  • kamailio-presence-modules – SIMPLE presence modules for Kamailio
  • kamailio-purple-modules – Provides the purple module, a multi-protocol IM gateway
  • kamailio-python-modules – contains the app_python module
  • kamailio-radius-modules – RADIUS modules for Kamailio
  • kamailio-redis-modules – Redis database connectivity module for Kamailio
  • kamailio-sctp-modules – sctp module for Kamailio
  • kamailio-snmpstats-modules – SNMP AgentX subagent module for Kamailio
  • kamailio-sqlite-modules – SQLite database connectivity module for Kamailio
  • kamailio-tls-modules – contains the TLS kamailio transport module
  • kamailio-unixodbc-modules – unixODBC database connectivity module for Kamailio
  • kamailio-utils-modules – Provides a set utility functions for Kamailio
  • kamailio-websocket-modules – Websocket module for kamailio
  • kamailio-xml-modules – XML based extensions for Kamailio’s Management Interface
  • kamailio-xmpp-modules – XMPP gateway module for Kamailio

The first set under explanation is Usrloc and Register module which take care of user persistance in Database and handling an incoming register request with authentication and validation.

The first set under explanation is Usrloc and Register module which take care of user persistance in Database and handling an incoming register request with authentication and validation.

Usrloc Module

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

Parameters:

  • nat_bflag
  • user_column
  • domain_column
  • contact_column
  • expires_column
  • q_column
  • callid_column
  • cseq_column
  • methods_column
  • flags_column
  • cflags_column
  • user_agent_column
  • received_column
  • socket_column
  • path_column
  • ruid_column
  • instance_column
  • server_id_column
  • connection_id_column
  • keepalive_column
  • partition_column
  • use_domain
  • desc_time_order
  • timer_interval
  • db_url
  • db_mode
  • db_load
  • db_insert_update
  • matching_mode
  • cseq_delay
  • fetch_rows
  • hash_size
  • preload
  • db_update_as_insert
  • db_check_update
  • timer_procs
  • xavp_contact
  • db_ops_ruid (int)
  • handle_lost_tcp (int)
  • close_expired_tcp (int)
  • expires_type (int)
  • db_raw_fetch_type (int)
  • db_insert_null (int)
  • skip_remote_socket (int)
  • db_timer_clean (int)
  • server_id_filter (int)

RPC Commands

ul.dump
ul.lookup table AOR
ul.rm table AOR
ul.rm_contact table AOR contact
ul.flush
ul.add
ul.db_users
ul.db_contacts
ul.db_expired_contacts

Statistics

users
contacts
expires
registered_users

Functions

ul_register_domain(name)
ul_insert_urecord(domain, aor, rec)
ul_delete_urecord(domain, aor)
ul_delete_urecord_by_ruid(domain, ruid)
ul_get_urecord(domain, aor)
ul_lock_udomain(domain)
ul_unlock_udomain(domain)
ul_release_urecord(record)
ul_insert_ucontact(record, contact, expires, q, callid, cseq, flags, cont, ua, sock)
ul_delete_ucontact (record, contact)
ul_get_ucontact(record, contact)
ul_get_all_ucontacts (buf, len, flags)
ul_update_ucontact(contact, expires, q, callid, cseq, set, res, ua, sock)
ul_bind_ursloc( api )
ul_register_ulcb(type ,callback, param)
ul_get_num_users()

Registrar Module

SIP registration processing logic can be defined here .

Path support – off , lazy , strict ( RFC 3327)

GRU ( Globally Routbale User agent URIs)  support –  public , temporary ( RFC 5627)

Dependencies :

  • usrloc – User Location Module.
  • sl – Stateless Replies.

Parameters :

  • default_expires
  • default_expires_range
  • expires_range
  • min_expires
  • max_expires
  • default_q
  • realm_prefix
  • append_branches
  • aor_avp (str)
  • case_sensitive
  • received_avp (str)
  • received_param
  • max_contacts
  • retry_after
  • sock_flag
  • sock_hdr_name
  • method_filtering
  • use_path
  • path_mode
  • path_use_received
  • path_check_local
  • reg_callid_avp
  • xavp_cfg
  • xavp_rcd
  • gruu_enabled
  • outbound_mode
  • regid_mode
  • flow_timer
  • contact_max_size

Functions :

save(domain, [, flags [, uri]])
lookup(domain [, uri])
lookup_branches(domain)
registered(domain [, uri [, match_option [, match_action]]])
add_sock_hdr(hdr_name)
unregister(domain, uri[, ruid])
reg_fetch_contacts(domain, uri, profile)
reg_free_contacts(profile)

Event Routes :

event_route[usrloc:contact-expired]

Statistics :

max_expires
max_contacts
default_expires
accepted_regs
rejected_regs

Ref : http://kamailio.org/docs/modules/stable/modules/registrar.html

Dialog Module

We know that dialog represent the p2p relationship between 2 sip clients and contains sequence of transactions along with routing information and facilitate sequencing of more messages

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

loadmodule "dialog.so"
..

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

Parameters :

  • enable_stats (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)
KSR.info("===== dialog module triggered event: " .. evname .. "\n");
if (evname == "dialog:end") or (evname == "dialog:failed") then
logger.log("info", "in dialog event callback with event-name - " .. evname .. " start CDR process ")
if not cdrProcess.post() then
logger.log("err", "Failed")
else
logger.log("info", "successfully posted")
core.exit()
end
end
end
  • h_id_start (int)
  • h_id_step (int)

Functions :

set_dlg_profile(profile,[value])
unset_dlg_profile(profile,[value])
is_in_profile(profile,[value])
get_profile_size(profile,[value],size)
dlg_isflagset(flag)
dlg_setflag(flag)
dlg_resetflag(flag)
dlg_bye(side)
dlg_refer(side, address)
dlg_manage()
dlg_bridge(from, to, op)
dlg_get(callid, ftag, ttag)
is_known_dlg()
dlg_set_timeout(timeout [, h_entry, h_id])
dlg_set_timeout_by_profile(profile, [value], timeout)
dlg_set_property(attr)
dlg_remote_profile(cmd, profile, value, uid, expires)
dlg_set_ruri()

Statistics :

active_dialogs
early_dialogs
processed_dialogs
expired_dialogs
failed_dialogs

RPC Commands :

dlg.list
dlg.list_ctx
dlg.dlg_list
dlg.dlg_list_ctx
dlg.terminate_dlg
dlg.end_dlg
dlg.profile_get_size
dlg.profile_list
dlg.bridge_dlg

Exported Variables :

$DLG_count
$DLG_status
$DLG_lifetime
$dlg(…)
$dlg_ctx(…)
$dlg_var(key)

Event Routes :

event_route[dialog:start] , event_route[dialog:end] , event_route[dialog:failed]

UAC module

This set deals with RTP proxy and RTP engine which are used for proxing media streams via kamailio server .


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

XHTTP

Provides basic HTTP/1.0 server functionality .

SIP requires a Content-Length header for TCP transport. But most HTTP clients do not set the content length for normal GET requests. Therefore, the core must be configured to allow incoming requests without content length header:

tcp_accept_no_cl=yes

Parameters :

url_skip : if there is a match , event route is not executed
modparam(“xhttp”, “url_skip”, “^/RPC2”)

url_match : if there is no match , event route is not executed
modparam(“xhttp”, “url_match”, “^/sip/”)

event_Callback : function in the kemi configuration file (embedded scripting language such as Lua, Python) to be executed instead of event_route[xhttp:request] block
Example :
modparam(“xhttp”, “event_callback”, “ksr_xhttp_event”)
and the event callback function implemented in Lua
function ksr_xhttp_event(evname)
KSR.info(“===== xhttp module triggered event: ” .. evname .. “\n”);
return 1;
end

Function

xhttp_reply(code, reason, ctype, body) – Send back a reply with content-type and body.

event_route[xhttp:request] {
xhttp_reply("200", "OK", "" , "");
or 
xhttp_reply("403", "Forbidden", "", "");
}

Event Routes

xhttp:request
The event route is executed when a new HTTP request is received.

event_route[xhttp:request] {
xhttp_reply(“200”, “OK”, “text/html”, “<html><body>OK – [$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).

-tbd

IPTV ( Internet Based Television )

We know the power of Internet protocol suit as it takes on the world of telecom . Alreday half of Communication has been transferred from legacy telecom signalling protocols like SS7 to IP based communication ( Skype , Hangouts , whatsapp , facebook call ) . The TV service providers too are largely investing in IP based systems like SIP and IMS to deliver their content over Telecom’s IP based network ( Packet switched ).

A consumer today wants HD media content anytime anywhere . The traditional TV solutions just dont match upto the expectations anymore . The IPTV provider in todays time must make investments to deliver content that is media-aware, and device-aware. Not only this it should be  personal, social, and interactive . after all its all about user  experience.

Few popular applications for IPTV solutions developers are

  • Menu overlay with detailed description of channels , categories , programs , movies
  • Replay option also referred to as timeshift . It allows a user to pause , resume and  record the show in his absence and view it later
  • Video on demand which concerns paying and viewing music albums , movies etc on demand
  • Live streaming of events such as president speech , tennis match etc .

Application that can be build around the IPTV context

  • Record and Playback content
  • Information overlay on streaming content
  • Social networking services integrated with IPTV content
  • Parental Control to realtime view , monitor and control what your child is watching on the IPTV
  • Watch the surveillance  footage from IP cameras anywhere
  • Real time communication on IPTV  with advanced features like call continuity , content sync .

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 .

Rich features set suiting to telephony domain that includes IMS extensions for VoLTE; ENUM; DID and least cost routing; load balancing; routing fail-over; Json and XMLRPC control interface, SNMP monitoring.

To integrate with a carrier grade telecom network as SBC / gateway / inbound/outbound proxy , it can act as IPv4-IPv6 gateway , UDP/TCP/SCTP/WS translator and even had NAT and anti DOS attack support .

If Kamailio is the central to the VoIP system it can also perform accounting with rich database extensions Mysql PostgreSQL UnixODBC Berkeley DB Oracle Redis, MongoDB Cassandra etc

  • Kamailio is SIP (RFC3261) compliant

It can work as Registrar or Location server. For SIP call logic it can become a Proxy or SIP Application server. Can also act like a Redirect , Dispatcher or simply a SIP over websocket server.

  • 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 with Scripting and programming

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
    • I-CSCF, P-CSCF, S-CSCF
    • 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

Scalability:

  • 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

Logs

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/kamailio.pid -m 4096 -M 128 -u root -g root

Installation and Configuration

Installing kamailio from git repo

clone kamailio from their github https://github.com/kamailio/kamailio

goto desired branch

The contents of clonned folder are

COPYING ChangeLog INSTALL ISSUES Makefile README README.md 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.

SIP_DOMAIN=kamailio.org

SIP_DOMAIN=17.3.4.5

chrooted directory

$CHROOT_DIR=”/path/to/chrooted/directory”

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

DBENGINE=MYSQL

Run kamdbctl to create users and database now

kamdbctl create

the database created is name kamailio and its tables are

+---------------------+
 | 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                |
 +---------------------+

Kamctlrc

The Kamailio configuration file for the control tools. Can set variables used in the kamctl and kamdbctl setup scripts. Per default all variables here are commented out, the control tools will use their internal default values. This file lets to edit  SIP domain, the database engine, username/password/ to connect to database, etc.

## your SIP domain
 SIP_DOMAIN=13.126.169.58
## chrooted directory
# $CHROOT_DIR="/path/to/chrooted/directory"
## database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE
# by default none is loaded

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

 DBENGINE=MYSQL
## database host
# DBHOST=localhost
## 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)
# DBACCESSHOST=192.168.0.1

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

# DBROOTUSER="root"
## password for database super user
## - important: this is insecure, targeting the use only for automatic testing
## - known to work for: mysql
# DBROOTPW="dbrootpw"
## database character set (used by MySQL when creating database)
#CHARSET="latin1"
## user name column
# USERCOL="username"
# SQL definitions

# If you change this definitions here, then you must change them
# in db/schema/entities.xml too.
# FIXME
# FOREVER="2030-05-28 21:32:15"
# DEFAULT_Q="1.0"
# Program to calculate a message-digest fingerprint
# MD5="md5sum"
# awk tool
# AWK="awk"
# gdb tool
# GDB="gdb"

# If you use a system with a grep and egrep that is not 100% gnu grep compatible,
# e.g. solaris, install the gnu grep (ggrep) and specify this below.

grep tool
# GREP="grep"
# egrep tool
# EGREP="egrep"
# sed tool
# SED="sed"
# tail tool
# LAST_LINE="tail -n 1"
# expr tool
# EXPR="expr"

Describe what additional tables to install. Valid values for the variables below are yes/no/ask. With ask (default) it will interactively ask the user for an answer, while yes/no allow for automated, unassisted installs.

#If to install tables for the modules in the EXTRA_MODULES variable.

# INSTALL_EXTRA_TABLES=ask
# If to install presence related tables.
# INSTALL_PRESENCE_TABLES=ask
# If to install uid modules related tables.
# INSTALL_DBUID_TABLES=ask

 Define what module tables should be installed.

If you use the postgres database and want to change the installed tables, then you must also adjust the STANDARD_TABLES or EXTRA_TABLES variable accordingly in the kamdbctl.base script.

standard modules

# STANDARD_MODULES="
standard acc lcr domain group permissions registrar usrloc msilo
alias_db uri_db speeddial avpops auth_db pdt dialog dispatcher
dialplan"

extra modules

# EXTRA_MODULES="
imc cpl siptrace domainpolicy carrierroute userblacklist htable purple sca"
 type of aliases used: DB - database aliases; UL - usrloc aliases
- default: none , ALIASES_TYPE="DB"
control engine: RPCFIFO
 - default RPCFIFO
 CTLENGINE="RPCFIFO"

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

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

## ACL names - if VERIFY_ACL is set, only the ACL names from below list are accepted
# ACL_GROUPS="local ld int voicemail free-pstn"

## check if user exists (used by some commands such as acl);
## - default on (1); off (0)

# VERIFY_USER=1

## verbose - debug purposes - default '0'
# VERBOSE=1

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

# STORE_PLAINTEXT_PW=0

Kamailio START Options

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

# PID_FILE=/var/run/kamailio/kamailio.pid

Extra start options – default is: not set

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

Kamailio.cfg

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
#!define WITH_USRLOCDB
  • attacks detection and blocking (anti-flood protection)
  • NAT traversal

requires RTP proxy for RTP relay . NAT traversal support can be set by

#!define WITH_NAT
  • short dialing on server
  • multiple identities (aliases) for subscribers
  • multi-domain support
  • routing to a PSTN gateway
  • routing to a voicemail server
  • TLS encryption
  • instant messaging (pager mode with MESSAGE requests)
  • 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

define WITH_USRLOCDB

To enable presence server execute:


enable mysql

define WITH_PRESENCE

To enable nat traversal execute:

define WITH_NAT

Install RTPProxy: http://www.rtpproxy.org

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

define WITH_ALIASDB

To enable speed dial lookup execute:


enable mysql

define WITH_SPEEDDIAL

To enable multi-domain support execute:


enable mysql

define WITH_MULTIDOMAIN

To enable TLS support execute:


adjust CFGDIR/tls.cfg as needed

define WITH_TLS

To enable XMLRPC support execute:


define WITH_XMLRPC

adjust route[XMLRPC] for access policy

To enable anti-flood detection execute:

adjust pike and htable=>ipban settings as needed (default is block if more than 16 requests in 2 seconds and ban for 300 seconds)

define WITH_ANTIFLOOD

To block 3XX redirect replies execute:

define WITH_BLOCK3XX

To enable VoiceMail routing execute:

define WITH_VOICEMAIL

set the value of voicemail.srv_ip

adjust the value of voicemail.srv_port

To enhance accounting execute:


enable mysql

define WITH_ACCDB

add following columns to database


define WITH_MYSQL

define WITH_AUTH

define WITH_USRLOCDB

#!ifdef ACCDB_COMMENT

ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';

ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';

ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';

ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';

ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';

ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';

ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';

ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';

ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';

ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';

ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';

ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';

#!endif

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
 #!else
 #!define MULTIDOMAIN 0
 #!endif

 # 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
 #!define FLB_NATSIPPING 

 !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"&lt;/pre&gt;
 
 #!define WITH_WEBSOCKETS
 #!ifdef WITH_DEBUG
 debug=4
 log_stderror=yes
 #!else
 debug=2
 log_stderror=no
 #!endif

 memdbg=5
 memlog=5
 log_facility=LOG_LOCAL0
 fork=yes
 children=4
 
disable TCP (default on)
 #disable_tcp=yes
 enable_sctp = 0

disable the auto discovery of local aliases based on reverse DNS on IPs (default on)
 #auto_aliases=no

add local domain aliases
#alias=”sip.mydomain.com”

// port to listen to can be specified more than once if needed to listen on many ports
port=5060
#!ifdef WITH_TLS
enable_tls=yes
#!endif

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

#!ifdef WITH_PSTN
# PSTN GW Routing
# - pstn.gw_ip: valid IP or hostname as string value, example:
# pstn.gw_ip = "10.0.0.101" 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"
#!endif

ifdef WITH_VOICEMAIL
# VoiceMail Routing on offline, busy or no answer
# - by default Voicemail server IP is empty to avoid misrouting
voicemail.srv_ip = "" desc "VoiceMail IP Address"
voicemail.srv_port = "5060" desc "VoiceMail Port"
#!endif

Modules Section

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

#!ifdef WITH_SRCPATH
mpath="modules/"
#!else
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
#!endif

#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!endif

loadmodule "mi_fifo.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "mi_rpc.so"
loadmodule "acc.so"

#!ifdef WITH_AUTH
loadmodule "auth.so"
loadmodule "auth_db.so"
#!ifdef WITH_IPAUTH
loadmodule "permissions.so"
#!endif
#!endif

#!ifdef WITH_ALIASDB
loadmodule "alias_db.so"
#!endif

#!ifdef WITH_SPEEDDIAL
loadmodule "speeddial.so"
#!endif

#!ifdef WITH_MULTIDOMAIN
loadmodule "domain.so"
#!endif

#!ifdef WITH_PRESENCE
loadmodule "presence.so"
loadmodule "presence_xml.so"
#!endif

#!ifdef WITH_NAT
loadmodule "nathelper.so"
loadmodule "rtpproxy.so"
#!endif

#!ifdef WITH_TLS
loadmodule "tls.so"
#!endif

#!ifdef WITH_ANTIFLOOD
loadmodule "htable.so"
loadmodule "pike.so"
#!endif

#!ifdef WITH_XMLRPC
loadmodule "xmlrpc.so"
#!endif

#!ifdef WITH_DEBUG
loadmodule "debugger.so"
#!endif

#!ifdef WITH_WEBSOCKETS
loadmodule "xhttp.so"
#loadmodule "websocket.so"
loadmodule "nathelper.so"
#!endif

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

"src_user=$fU;src_domain=$fd;src_ip=$si;"

"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")

#!endif

usrloc params – enable DB persistency for location entries


#!ifdef WITH_USRLOCDB

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

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

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

#!endif

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


#!ifdef WITH_IPAUTH

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

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

#!endif

#!endif

alias_db params


#!ifdef WITH_ALIASDB

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

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

#!endif

speeddial params


#!ifdef WITH_SPEEDDIAL

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

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

#!endif

domain params

#!ifdef WITH_MULTIDOMAIN
modparam("domain", "db_url", DBURL)
modparam("domain", "register_myself", 1)
#!endif
#!ifdef WITH_PRESENCE

presence params

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

presence_xml params

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

WITH_NAT

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

nathelper params

 modparam("nathelper", "natping_interval", 30)
 modparam("nathelper", "ping_nated_only", 1)
 modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
 modparam("nathelper", "sipping_from", "sip:pinger@kamailio.org") 

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

#!endif

pike params

#!ifdef WITH_ANTIFLOOD

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

#!endif

xmlrpc params

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

debugger params

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

nathelper params

#!ifdef WITH_WEBSOCKETS
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
#!endif

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 
route(REQINIT);
 #!ifdef WITH_WEBSOCKETS 
    if (nat_uac_test(64)) {     
        force_rport();     
        if (is_method("REGISTER")) {          
            fix_nated_register();     
        } else {         
            fix_nated_contact();         
            if (!add_contact_alias()) {  
                   xlog("L_ERR", "Error aliasing contact \n");             
                   sl_send_reply("400", "Bad Request");                    exit;         }     } } 
#!endif 
# NAT detection 
route(NATDETECT); 
# CANCEL processing 
if (is_method("CANCEL")) {     
    if (t_check_trans()) {         
        route(RELAY);     
    }     
exit; 
} 

# handle requests within SIP dialogs 
route(WITHINDLG); 
### only initial requests (no To tag) 
# handle retransmissions 
if(t_precheck_trans()) { 
    t_check_trans(); 
    exit; 
} 
t_check_trans(); 

# authentication 
route(AUTH); 

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

if (is_method("INVITE|SUBSCRIBE")) 
record_route(); 

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

### requests for my local domains 
# handle presence related requests 
route(PRESENCE); 

# handle registrations 
route(REGISTRAR); 
if ($rU==$null) {     
# request with no Username in RURI     sl_send_reply("484","Address Incomplete");     
exit; 
} 
# dispatch destinations to PSTN route(PSTN); 

# user location service 
route(LOCATION); }

Wrapper for relaying requests

enable additional event routes for forwarded requests – serial forking, RTP relaying handling, a.s.o.

route[RELAY] {
if (is_method(“INVITE|BYE|SUBSCRIBE|UPDATE”)) {
if(!t_is_set(“branch_route”))
t_on_branch(“MANAGE_BRANCH”);
}
if (is_method(“INVITE|SUBSCRIBE|UPDATE”)) {
if(!t_is_set(“onreply_route”))
t_on_reply(“MANAGE_REPLY”);
}
if (is_method(“INVITE”)) {
if(!t_is_set(“failure_route”))
t_on_failure(“MANAGE_FAILURE”);
}
if (!t_relay()) {
sl_reply_error();
}
exit;
}

Per SIP request initial checks

route[REQINIT] { #!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");
                    exit;
                }
            }
            #!endif
         }
     exit;
     }

#sequential request within a dialog should  take the path determined by record-routing
    if (loose_route()) {
        route(DLGURI);
        if (is_method("BYE")) {
            setflag(FLT_ACC); # do accounting ...
            setflag(FLT_ACCFAILED); # ... even if the transaction fails
        }
        else if ( is_method("ACK") ) {
            # ACK is forwarded statelessy
            route(NATMANAGE);
        }
        else if ( is_method("NOTIFY") ) {
            # Add Record-Route for in-dialog NOTIFY as per RFC 6665.
            record_route();
        }
        route(RELAY);
        exit;
    }

    if (is_method("SUBSCRIBE") && uri == myself) {
    # in-dialog subscribe requests
        route(PRESENCE);
        exit;
    }

if ( is_method("ACK") ) {
    if ( t_check_trans() ) {
        # no loose-route, but stateful ACK;
        # must be an ACK after a 487
        # or e.g. 404 from upstream server
        route(RELAY);
        exit;
    } else {
        # ACK without matching transaction ... ignore and discard
        exit;
    }
}

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


Handle SIP registrations





User location service

route[LOCATION] {

#!ifdef WITH_SPEEDDIAL
# search for short dialing - 2-digit extension
if($rU=~"^[0-9][0-9]$")
    if(sd_lookup("speed_dial"))
    route(SIPOUT);
#!endif

#!ifdef WITH_ALIASDB
# search in DB-based aliases
    if(alias_db_lookup("dbaliases"))
    route(SIPOUT);
#!endif

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

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

route(RELAY);
exit;
}

Presence server processing

route[PRESENCE] {

if(!is_method("PUBLISH|SUBSCRIBE"))
return;

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

#!ifdef WITH_PRESENCE
if (!t_newtran()) {
    sl_reply_error();
    exit;
}

if(is_method("PUBLISH")) {
    handle_publish();
    t_release();
} else if(is_method("SUBSCRIBE")) {
    handle_subscribe();
    t_release();
}
exit;
#!endif

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

IP authorization and user authentication

route[AUTH] {
#!ifdef WITH_AUTH

#!ifdef WITH_IPAUTH
if((!is_method("REGISTER")) && allow_source_address()) {
    # source IP allowed
    return;
}
#!endif

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

    # user authenticated - remove auth header
    if(!is_method("REGISTER|PUBLISH"))
        consume_credentials();
    }

# if caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
    if (from_uri!=myself && uri!=myself) {
        sl_send_reply("403","Not relaying");
        exit;
    }

#!endif
return;
}

Caller NAT detection

route[NATDETECT] {
#!ifdef WITH_NAT
force_rport();

if (nat_uac_test("19")) {
    if (is_method("REGISTER")) {
        fix_nated_register();
    } else {
        if(is_first_hop())
            set_contact_alias();
    }
    setflag(FLT_NATS);
}
#!endif
return;
}

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")) {
            setbflag(FLB_NATB);
        }
     }
}
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB)))
return;

rtpproxy_manage("co");

if (is_request()) {
    if (!has_totag()) {
        if(t_is_branch_route()) {
            add_rr_param(";nat=yes");
        } 
    }
}

if (is_reply()) {
    if(isbflagset(FLB_NATB)) {
        if(is_first_hop())
        set_contact_alias();
    }
}

#!endif
return;
}

URI update for dialog requests

route[DLGURI] {
#!ifdef WITH_NAT
if(!isdsturiset()) {
    handle_ruri_alias();
}
#!endif
return;
}

Routing to foreign domains

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

append_hf("P-hint: outbound\r\n");
route(RELAY);
exit;
}

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

# route to PSTN dialed numbers starting with '+' or '00'
# (international format)
# - update the condition to match your dialing rules for PSTN routing
if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))
return;

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

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

route(RELAY);
exit;
#!endif

return;
}

XMLRPC routing

#!ifdef WITH_XMLRPC
route[XMLRPC] {
# allow XMLRPC from localhost
if ((method=="POST" || method=="GET") && (src_ip==127.0.0.1)) {
# close connection only for xmlrpclib user agents
    if ($hdr(User-Agent) =~ "xmlrpclib")
        set_reply_close();
        set_reply_no_connect();
        dispatch_rpc();
    exit;
}
send_reply("403", "Forbidden");
exit;
}
#!endif

Routing to voicemail server

route[TOVOICEMAIL] {
#!ifdef WITH_VOICEMAIL
if(!is_method("INVITE|SUBSCRIBE"))
return;

# 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");
    return;
}
if(is_method("INVITE")) {
    if($avp(oexten)==$null)
        return;
    $ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)+ ":" + $sel(cfg_get.voicemail.srv_port);
} else {
    if($rU==$null)
        return;
    $ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip)
+ ":" + $sel(cfg_get.voicemail.srv_port);
}
route(RELAY);
exit;
#!endif

return;
}

Manage outgoing branches

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

Manage incoming replies

onreply_route[MANAGE_REPLY] {
    xdbg("incoming reply\n");
    if(status=~"[12][0-9][0-9]")
        route(NATMANAGE);
}

Manage failure routing cases

failure_route[MANAGE_FAILURE] {
route(NATMANAGE);

if (t_is_canceled()) {
    exit;
}

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

#!ifdef WITH_VOICEMAIL
# serial forking
# - route to voicemail on busy or no answer (timeout)
if (t_check_status("486|408")) {
    $du = $null;
    route(TOVOICEMAIL);
    exit;
}
#!endif
}

Supports pseudo-variables to access and manage parts of the SIP messages and attributes specific to users and server.  Transformations to modify existing pseudo-variables, accessing only the wanted parts of the information. 

Already has over 1000 parameters, variables and functions exported to config file. Supports runtime update framework – to avoid restarting the SIP server when needing to change the config parameters

Tools

kamctl

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.

kamdbctl

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

Valid values are: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT.

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.

kamcmd

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

siremis

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

———————————–

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 )

Proxying Media Streams via Kamailio

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)

Functions

set_rtp_proxy_set(setid) – Sets the Id of the rtpproxy set to be used for the next unforce_rtp_proxy(), rtpproxy_offer(), rtpproxy_answer() or rtpproxy_manage() command

rtpproxy_offer([flags [, ip_address]]) – to make the media pass through RTP the SDP is altered. Value of flag can be
1 – append first Via branch to Call-ID when sending command to rtpproxy.
2 – append second Via branch to Call-ID when sending command to rtpproxy. See flag ‘1’ for its meaning.
3 – behave like flag 1 is set for a request and like flag 2 is set for a reply
a – flags that UA from which message is received doesn’t support symmetric RTP. (automatically sets the ‘r’ flag)
b – append branch specific variable to Call-ID when sending command to rtpproxy
l – force “lookup”, that is, only rewrite SDP when corresponding session already exists in the RTP proxy
i, e – direction of the SIP message when rtpproxy is running in bridge mode. ‘i’ is internal network (LAN), ‘e’ is external network (WAN). Values ie , ei , ee and ii
x – shortcut for using the “ie” or “ei”-flags, to do automatic bridging between IPv4 on the “internal network” and IPv6 on the “external network”. Differentiated by IP type in the SDP, e.g. a IPv4 Address will always call “ie” to the RTPProxy (IPv4(i) to IPv6(e)) and an IPv6Address will always call “ei” to the RTPProxy (IPv6(e) to IPv4(i))
f – instructs rtpproxy to ignore marks inserted by another rtpproxy in transit to indicate that the session is already gone through another proxy. Allows creating a chain of proxies
r – IP address in SDP should be trusted. Without this flag, rtpproxy ignores address in the SDP and uses source address of the SIP message as media address which is passed to the RTP proxy
o – flags that IP from the origin description (o=) should be also changed.
c – flags to change the session-level SDP connection (c=) IP if media-description also includes connection information.
w – flags that for the UA from which message is received, support symmetric RTP must be forced.
zNN – perform re-packetization of RTP traffic coming from the UA which has sent the current message to increase or decrease payload size per each RTP packet forwarded if possible. The NN is the target payload size in ms, for the most codecs its value should be in 10ms increments, however for some codecs the increment could differ (e.g. 30ms for GSM or 20ms for G.723).
ip_address denotes the address of new SDP

such as : rtpproxy_offer(“FRWOC+PS”) is
rtpengine_offer(“force trust-address symmetric replace-origin replace-session-connection ICE=force RTP/SAVPF”);

route { 
...
if (is_method("INVITE"))
{
if (has_body("application/sdp"))
{
if (rtpproxy_offer()) t_on_reply("1");
} else {
t_on_reply("2");
}
}

if (is_method("ACK") && has_body("application/sdp")) rtpproxy_answer();
...
}
onreply_route[1] {
if (has_body("application/sdp")) rtpproxy_answer();
}
onreply_route[2] {
if (has_body("application/sdp")) rtpproxy_offer();
}

rtpproxy_answer([flags [, ip_address]])- rewrite SDP to proxy media , it can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.

rtpproxy_destroy([flags]) – tears down RTP proxy session for current call. Flags are ,
1 – append first Via branch to Call-ID
2 – append second Via branch to Call-ID
b – append branch specific variable to Call-ID
t – do not include To tag to “delete” command to rtpproxy thus causing full call to be deleted

unforce_rtp_proxy()

rtpproxy_manage([flags [, ip_address]]) – Functionality is to use predfined logic for handling requests
If INVITE with SDP, then do rtpproxy_offer()
If INVITE with SDP, when the tm module is loaded, mark transaction with internal flag FL_SDP_BODY to know that the 1xx and 2xx are for rtpproxy_answer()
If ACK with SDP, then do rtpproxy_answer()
If BYE or CANCEL, or called within a FAILURE_ROUTE[], then call unforce_rtpproxy().
If reply to INVITE with code >= 300 do unforce_rtpproxy()
If reply with SDP to INVITE having code 1xx and 2xx, then do rtpproxy_answer() if the request had SDP or tm is not loaded, otherwise do rtpproxy_offer()
This function can be used from ANY_ROUTE.

rtpproxy_stream2uac(prompt_name, count) – stream prompt/announcement pre-encoded with the makeann command. The uac/uas suffix selects who will hear the announcement relatively to the current transaction – UAC or UAS. Also used for music on hold (MOH).
Params : prompt_name – path name of the prompt to stream
count – number of times the prompt should be repeated. When count is -1, the streaming will be in loop indefinitely until the appropriate rtpproxy_stop_stream2xxx is issued.
Example rtpproxy_stream2xxx usage

if (is_method("INVITE")) { 
rtpproxy_offer();
if (is_audio_on_hold()) {
rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", "-1");
} else {
rtpproxy_stop_stream2uas();
};
};

rtpproxy_stream2uas(prompt_name, count)

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

rtpproxy_stop_stream2uas()

start_recording()
Exported Pseudo Variables

$rtpstat
RPC Commands

rtpproxy.enable
rtpproxy.list

RTP Engine

media streams to be proxied via an RTP proxy.

loadmodule "rtpengine.so"
...

# ----- 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 : https://github.com/sipwise/rtpengine

Parameters

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

Functions

set_rtpengine_set(setid[, setid])
rtpengine_offer([flags])
rtpengine_answer([flags])
rtpengine_delete([flags])
rtpengine_query([flags])
rtpengine_manage([flags])
start_recording([flags])
stop_recording([flags])
Exported Pseudo Variables
$rtpstat

RPC Commands

rtpengine.reload
rtpengine.enable proxy_url/all 0/1
rtpengine.show proxy_url/all
rtpengine.ping proxy_url/all
rtpengine.get_hash_total

Service Creation Environment (SCE ) for SIP Applications

I hoped of making a SIP application Development environment a year back and worked towards it earnestly . Sadly I wasn’t able to complete the job yet I have decided to share a few things about it here .

Aim :

Develop  a SCE ( Service Creation Environment ) to addresses all aspects of lifecycle of a Service, right from creation/development, orchestration, execution/delivery, Assurance and Migration/Upgrade of services.

Similar market products :

  • Open/cloud Rhino
  • Mobicents and Telestax

Limitations of open source/other market products:

  • Free versions of the Service Creation Environments do not offer High Availability.
  • High Cost of Deployment grade versions.

Solution Description

I propose a in-house Java based Service Creation Environment “SLC SCE”. The SLC SCE will enable creation of JAINSLEE based SIP  services. It can be used to develop and deploy carrier-grade applications that use SS7 and IMS based protocols such as INAP, CAP, Diameter and SIP as well as IT / Web protocols such as HTTP and XML.

Benefits:

  • Service Agility
  • Significantly Lower price points
  • Open Standards eliminate Legacy SCP Lock-in

Timeline

  • Java-based service creation environment (SCE) – 1.5 Months
  • Graphical User Interface (GUI) and schematic representations to help in the design, maintenance and support of applications – 1.5 months
  • SIP Resource Adapter – 1 month

Architecture

Service Creation Environment (SCE) for SIP Applications

Service Creation Environment (SCE) for SIP Applications

In essence it encompasses the idea of developing the following

  1. SIP stack
  2. Javascript API’s
  3. Java Libraries for calling SIP stack
  4. Eclipse plugin to work with the SIP application development process
  5. Visual Interface to view the logic of application and possible errors / flaws
  6. SDKs (  Service Development Kit) , which are development Environment themselves

Extra Effort required to put in to make the venture successful

  1. Demo applications for basic SIP logic like Call screening , call rerouting .
  2. tutorial to create , deploy and run application from scratch . Aimed at all sections ie web developer , telecom engineer , full stack developer etc .
  3. Some opensource implementation on public repositories like Github , Google code , SourceForge
  4. Perform active problem solving on Stackoverflow , CodeRanch , Google groups and  other forums .

—————————————————————

OfficeSIP

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

officesip0

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

officesip1

3.Installation screen appears as follows

officesip2

4. Terms and conditions

officesip3

5. Destination folder for installation

officesip4

6. Installing

officesip5

7. Validating install

officesip6

8. Installation completed

officesip7

9. Launch icon on dekstop

officesip8

10 . Office SIP web login screen

officesip9

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

officesip10

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

officesip11

13. add users that will be registering to officeSIP server

officesip13

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

officesip14_001

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 startweblogic.sh script

4. Open Web console on url : http://127.0.0.1:7001/console. 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
src
build
src
web
build.xml

The SIP servlet are put side directory structure of src

For example : sample application for Call screening

package com.altanai.voice;
import java.io.IOException;
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”);
super.init(config);
}
protected void doInvite(SipServletRequest req) throws java.lang.IllegalArgumentException,java.lang.IllegalStateException,javax.servlet.ServletException,java.io.IOException
{
System.out.println(“Received an Invite Request”);
if(req.getFrom().toString().indexOf(“alice”)!=-1)
{
req.createResponse(406).send();
System.out.println(“User is blocked”);
}
else
{
req.createResponse(200).send();
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