Opensips Modules

If you are new are opensips you cab read Over view of Opensisp SIP server here https://telecom.altanai.com/2018/06/06/opensips/

Opensips

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.

This article talks about modules and subparts of Opensips and their role in defining the purpose and application of Opensips which can be as an lighweight proxy to loadbalancer or even as AAA server.

Dispatcher Module

This modules implements a dispatcher for destination addresses. It computes hashes over parts of the request and selects an address from a destination set. The selected address is used then as outbound proxy.
The module can be used as a stateless load balancer, having no guarantee of fair distribution.

Path to the file with destination sets by default is “/etc/opensips/dispatcher.list” or “/usr/local/etc/opensips/dispatcher.list”.

modparam("dispatcher", "list_file", "/var/run/opensips/dispatcher.list")

db_url is used to load the sets of gateways from the database

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

table_name loads the sets of gateways from the database. Default value is “dispatcher”.

modparam("dispatcher", "table_name", "my_dispatcher")

setid_col (string) – storing the gateway’s group id. Default value is “setid”.

modparam("dispatcher", "setid_col", "groupid")

destination_col (string) – destination’s sip uri.

modparam("dispatcher", "destination_col", "uri")

flags_col (string) – The column’s name in the database storing the flags for destination uri.

modparam("dispatcher", "flags_col", "dstflags")

force_dst (int) – If set to 1, force overwriting of destination address when that is already set. Default value is “0”.

modparam("dispatcher", "force_dst", 1)

flags (int) – affect dispatcher’s behaviour. Default value is “0”.

  • If flag 1 is set only the username part of the uri will be used when computing an uri based hash.
  • If no flags are set the username, hostname and port will be used The port is used only if different from 5060 (normal sip uri) or 5061 (in the sips case).
  • If flag 2 is set, then the failover support is enabled. The functions exported by the module will store the rest of addresses from the destination set in AVP, and use these AVPs to contact next address when the current-tried fails.
modparam("dispatcher", "flags", 3)

use_default (int) – If the parameter is set to 1, the last address in destination set is used as last option to send the message. For example, it is good when wanting to send the call to an anouncement server saying: “the gateways are full, try later”. Default value is “0”.

modparam("dispatcher", "use_default", 1)

dst_avp (str) – The name of the avp which will hold the list with addresses, in the order they have been selected by the chosen algorithm.

modparam("dispatcher", "dst_avp", "$avp(i:271)")

If use_default is 1, the value of last dst_avp_id is the last address in destination set. The first dst_avp_id is the selected destinations. All the other addresses from the destination set will be added in the avp list to be able to implement serial forking.

grp_avp (str) – The name of the avp storing the group id of the destination set. Good to have it for later usage or checks. Default is null.

modparam("dispatcher", "grp_avp", "$avp(i:272)")

cnt_avp (str) – The name of the avp storing the number of destination addresses kept in dst_avp avps.

modparam("dispatcher", "cnt_avp", "$avp(i:273)")

hash_pvar (str) – String with PVs used for the hashing algorithm like to do hashing over custom message parts.Default value is “null” – disabled.

modparam("dispatcher", "hash_pvar", "$avp(i:273)")

setid_pvar (str) – name of the PV where to store the set ID (group ID) when calling ds_is_from_list() with no parameter.

modparam("dispatcher", "setid_pvar", "$var(setid)")

ds_ping_method (string) – With this Method you can define, with which method you want to probe the failed gateways. This method is only available, if compiled with the probing of failed gateways enabled. Default value is “OPTIONS”.

modparam("dispatcher", "ds_ping_method", "INFO")

ds_ping_from (string) – With this Method you can define the “From:”-Line for the request, sent to the failed gateways. This method is only available, if compiled with the probing of failed gateways enabled. Default value is “sip:dispatcher@localhost”.

modparam("dispatcher", "ds_ping_from", "sip:proxy@sip.somehost.com")

ds_ping_interval (int – With this Method you can define the interval for sending a request to a failed gateway. This parameter is only used, when the TM-Module is loaded. If set to “0”, the pinging of failed requests is disabled.Default value is “10”.

modparam("dispatcher", "ds_ping_interval", 30)

ds_probing_threshhold (int) – If you want to set a gateway into probing mode, you will need a specific number of requests until it will change from “active” to probing. The number of attempts can be set with this parameter. Default value is “3”.

modparam("dispatcher", "ds_probing_threshhold", 10)

ds_probing_mode (int) – Controls what gateways are tested to see if they are reachable.

  • If set to 0, only the gateways with state PROBING are tested,
  • if set to 1, all gateways are tested. If set to 1 and the response is 407 (timeout), an active gateway is set to PROBING state. Default value is “0”.
modparam("dispatcher", "ds_probing_mode", 1)

options_reply_codes (str) – The codes defined here will be considered as valid reply codes for OPTIONS messages used for pinging, apart for 200. Default value is “NULL”.

modparam("dispatcher", "options_reply_codes", "501, 403")

ds_select_dst(set, alg) – The method selects a destination from addresses set. Algorithm used to select the destination address can be :

  • “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.
ds_select_dst("1", "0");

You can use ‘ds_next_dst()’ to use next address to achieve serial forking to all possible destinations. This function can be used from REQUEST_ROUTE.

ds_select_domain(set, alg) – selects a destination from addresses set and rewrites the host and port from R-URI. This function can be used from REQUEST_ROUTE.

ds_next_dst() – Takes the next destination address from the AVPs with id ‘dst_avp_id’ and sets the dst_uri (outbound proxy address). This function can be used from FAILURE_ROUTE.

ds_next_domain() – Takes the next destination address from the AVPs with id ‘dst_avp_id’ and sets the domain part of the request uri. This function can be used from FAILURE_ROUTE.

ds_mark_dst() – Mark the last used address from destination set as inactive, in order to be ingnored in the future. In this way it can be implemented an automatic detection of failed gateways. When an address is marked as inactive, it will be ignored by ‘ds_select_dst’ and ‘ds_select_domain’. This function can be used from FAILURE_ROUTE.

ds_mark_dst(“s”) – Mark the last used address from destination set as :

  • inactive (“i”/”I”/”0”),
  • active (“a”/”A”/”1”) or
  • probing (“p”/”P”/”2”).

With this function, an automatic detection of failed gateways can be implemented. When an address is marked as inactive or probing, it will be ignored by ‘ds_select_dst’ and ‘ds_select_domain’.

ds_is_from_list() – This function returns true, if the current request comes from a host from the dispatcher-list; otherwise false. This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE and ONREPLY_ROUTE.

ds_is_from_list(“group”) – This function returns true, if the current request comes from a host in the given group of the dispatcher-list; otherwise false.

This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE and ONREPLY_ROUTE.

Exported MI Functions

ds_set_state – Sets the status for a destination address (can be use to mark the destination as active or inactive).
Parameters:
state : state of the destination address
“a”: active
“i”: inactive
“p”: probing
group: destination group id
address: address of the destination in the group

MI FIFO Command Format:
:ds_set_state:reply_fifo_file
state
group
address
empty_line

ds_list – It lists the groups and included destinations.

MI FIFO Command Format:
:ds_list:reply_fifo_file
empty_line

ds_reload – reloads the groups and included destinations.

MI DATAGRAM Command Format:

    ":ds_reload:\n."

Installation and Running

Destination List File – Each destination point must be on one line. First token is the set id, followed by destination address. Optionally, the third field can be flags value (1 – destination inactive, 2 – destination in probing mod — you can do bitwise OR to set both flags). The set id must be an integer value. Destination address must be a valid SIP URI. Empty lines or lines starting with “#” are ignored.

Exmaple of a dispatcher list file
line format
setit(integer) destination(sip uri) flags (integer, optional)

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

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

module loading

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

db_text Module

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.

Internal format of a db_text table

column definition name(type,attr) where types can be int , double , str and attributes be auto , null ,
* each other line is a row with data. The line ends with “\n”.
* the fields are separated by “:”.
* no value between two ‘:’ (or between ‘:’ and start/end of a row) means “null” value.
* next characters must be escaped in strings: “\n”, “\r”, “\t”, “:”.
* 0 — the zero value must be escaped too.

Sample of a db_text table ,

id(int,auto) name(str) flag(double) desc(str,null)
1:nick:0.34:a\tgood\: friend
2:cole:-3.75:colleague
3:bob:2.50:

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.

modparam("db_text", "db_mode", 1)

Exported MI Functions

dbt_dump – Write back to hard drive modified tables.

opensipsctl fifo dbt_dump

dbt_reload – Causes db_text module to reload cached tables from disk. Parameters:
1 db_name (optional) – database name to reload.
2 table_name (optional, but cannot be present without the
db_name parameter) – specific table to reload.

MI FIFO Command Format:
opensipsctl fifo dbt_reload
opensipsctl fifo dbt_reload /path/to/dbtext/database
opensipsctl fifo dbt_reload /path/to/dbtext/database table_name

Installation and Running

Compile the module and load it instead of mysql or other DB modules.

Load the db_text module

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

Using db_text with basic OpenSIPS configuration

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 and making initial sanity checks — messages with max_forwards==0, or excessively long requests

-- 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{
    if (!mf_process_maxfwd_header("10")) {
        sl_send_reply("483","Too Many Hops");
        exit;
    };
    if ($ml >=  65535 ) {
        sl_send_reply("513", "Message too big");
        exit;
    };


if (!$rm=="REGISTER") record_route();


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

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

After the starting of a transaction such as REGISTER or INVITE we ensure that subsequent messages withing a dialog should take the path determined by record-routing using “record_route” function.

Combination of opensips working scenarios scripts with code is at https://github.com/altanai/opensipsexamples.


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

Telephony Solutions with Kamailio

  • Features
    • RFC3261 compliant
    • Customisable and Felxible – Modular Architecture
    • Call routing and control
    • NAT traversal
    • Data store integration
    • Transport Layers supported
    • Asynchronous TCP, UDP and SCTP
    • Secure Communication ( TLS + AAA)
    • IP and DNS
    • Accounting
    • External Integration
    • Rich Communication Services ( RCS)
  • Kamailio (OpenSER) SIP Server v4.3- default configuration script
    • debug
    • authentication
    • persistent user location
    • presence
    • nat traversal
    • RTPProxy
    • PSTN gateway
    • Block 3XX redirect repliest
    • Database aliases lookup
    • speed dial
    • multi-domain support
    • XMLRPC
    • anti-flood detection
  • Routing Logic
    • WITHINDLG
    • LOCATION
    • PRESENCE
    • AUTH
    • NATDETECT
    • NATMANAGE
    • DLGURI
    • SIPOUT
    • PSTN
    • XMLRPC
    • TOVOICEMAIL
    • MANAGE_BRANCH
    • MANAGE_REPLY
    • MANAGE_FAILURE
  • kamctl
  • kamdbctl
  • Kamctlrc
  • Kamailio.cfg
  • kamcmd
  • siremis

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 .

Features

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

  • Kamailio is SIP (RFC3261) compliant

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

  • Customisable and Felxible

It can be embedded to devices as the binary file is small size. Additional modules can be appended for more functions with the same core.

Modular architecture – core, internal libraries , module interface and ability to extend functionality with scripts such as LUA, Kamailio can be readily integrated to a VOIP ecosystem.

Kamailio Architecture , Core and Modules.

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

Kamailio Transaction management describes branches, serial and paralle forking and TM module.

Also NAT traversal support for SIP and RTP traffic ( suited to be WebRTC server ) . Read more about kamailio DNS subsystem management , load balancing , NAT and NAThelper modules in Kamailio DNS and NAT.

Kamailio as a WebRTC SIP Server with mdules websocket , TLS , NATHelper  and JSSIP integration.

Among other features it offers load balancing with many distribution algorithms and failover support, flexible least cost routing , routing failover and replication for High Availability (HA).

Can be readily integrated with external databases, caches, notification system ( SNS , APNS , GCM ), VoIP monitors, CDR processors, API systems etc for  efficient call processing.

  • Transport Layers supported 
    • UDP, TCP, TLS and SCTP
    • IPv4 and IPv6
    • gateways via (IPv4 to IPv6, UDP to TLS, a.s.o.)
    • SCTP multi-homing and multi-streaming
    • WebSocket for WebRTC 
  • Asynchronous TCP, UDP and SCTP

Asynchronous SIP message processing and  inter-process message queues communication system

  • Secure Communication ( TLS  + AAA)
    • Digest SIP User authentication
    • Authorization via ACL or group membership
    • IP and Network authentication
    • TLS support for SIP signaling
    • transparent handling of SRTP for secure audio
    • TLS domain name extension support
    • authentication and authorization against database (MySQL, PostgreSQL, UnixODBC, BerkeleyDB, Oracle, text files), RADIUS and DIAMETER

Kamailio Security here for snaity, ACL permission , firewall , flood detection , topology hiding and digests.

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

Lua Scripts for kamailio Routing – KEMI interpreter , function , routing logic, PV variables

  • 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). More details on Kamailio as Inbound/Outbound proxy or Session Border Controller (SBC) here

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

Scalability with Kamailio system

  • 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

Kamaiio Logs tailing

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

Read RTP engine on kamailio SIP server which focuses on setting up sipwise rtpegine to proxy rtp traffic from kamailio app server. Also daemon and kernal modules. ,transcoding , in-kernel packet forwarding , ngcontrol protocol etc.

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=1.1.1.1
## chrooted directory
# $CHROOT_DIR="/path/to/chrooted/directory"
## database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE
# by default none is loaded

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

DBENGINE=MYSQL
## database host
# DBHOST=localhost
# DBPORT=3306
## database name (for ORACLE this is TNS name)
# DBNAME=kamailio
# database path used by dbtext, db_berkeley or sqlite
# DB_PATH="/usr/local/etc/kamailio/dbtext"
database read/write user
# DBRWUSER="kamailio"
## password for database read/write user
# DBRWPW="kamailiorw"

database read only user

# DBROUSER="kamailioro"
## password for database read only user
# DBROPW="kamailioro"
## database access host (from where is kamctl used)
# DBACCESSHOST=192.168.0.1

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

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

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

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

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

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

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

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

 Define what module tables should be installed.

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

standard modules

# STANDARD_MODULES="
standard acc lcr domain group permissions registrar usrloc 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:

debugger params

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

To run in debug mode: 

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

To enable mysql: 

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

To enable authentication

enable mysql
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 :

enable mysql
define WITH_USRLOCDB

To enable presence server :

enable mysql
define WITH_PRESENCE

To enable nat traversal :

define WITH_NAT

RTPProxy

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

PSTN gateway

To enable PSTN gateway routing :

define WITH_PSTN

set the value of pstn.gw_ip

check route[PSTN] for regexp routing condition.

#!ifdef WITH_PSTN
pstn.gw_ip = "" desc "PSTN GW Address"
pstn.gw_port = "" desc "PSTN GW Port"
#!endif

Database aliases lookup

To enable database aliases lookup :

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
...
 #!ifdef WITH_MULTIDOMAIN# - the value for 'use_domain' parameter
 #!define MULTIDOMAIN 1
 #!else
 #!define MULTIDOMAIN 0
 #!endif

To enable TLS support execute:

adjust CFGDIR/tls.cfg as needed
define WITH_TLS

To enable XMLRPC support :

define WITH_XMLRPC

adjust route[XMLRPC] for access policy

To enable anti-flood detection execute:

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

define WITH_ANTIFLOOD
...
      
route[REQINIT] { 
  #!ifdef WITH_ANTIFLOOD 
  # flood detection from same IP and traffic ban      
  if(src_ip!=myself) {                
    if($sht(ipban=>$si)!=$null) {             
       # ip is already blocked             
       xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");             
       exit;        
     }        
     if (!pike_check_req()) {             
       xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");             
       $sht(ipban=>$si) = 1;             
       exit;        
     }     
  }     

  if($ua =~ "friendly-scanner") {        
    sl_send_reply("200", "OK");         
    exit;     
  } 
  #!endif 
.. 
}

To block 3XX redirect replies execute:

define WITH_BLOCK3XX

To enable VoiceMail routing :

define WITH_VOICEMAIL

set the value of voicemail.srv_ip and adjust the value of voicemail.srv_port

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

To enhance accounting execute:

enable mysql
define WITH_ACCDB

add following columns to database

define WITH_MYSQL
define WITH_AUTH
define WITH_USRLOCDB

#!ifdef ACCDB_COMMENT
ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';
ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';
ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
#!endif

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

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



 # 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"</pre>
 
 #!define WITH_WEBSOCKETS
disable TCP (default on)
#disable_tcp=yes
enable_sctp = 0

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

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

//port to listen
port=5060
#!ifdef WITH_TLS
enable_tls=yes
#!endif

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

Modules Section

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

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

Load modules

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

modules params for mi_fifo,ctl, tm and rr

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

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

----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 30sec
modparam("tm", "fr_timer", 30000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)

----- rr params -----
# set next param to 1 to add value to ;lr param (helps with some UAs)
modparam("rr", "enable_full_lr", 0)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)

registrar params

modparam("registrar", "method_filtering", 1)
/* uncomment the next line to disable parallel forking via location */
# modparam("registrar", "append_branches", 0)
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
# max value for expires of registrations
modparam("registrar", "max_expires", 3600)
# set it to 1 to enable GRUU
modparam("registrar", "gruu_enabled", 0)

usrloc params – enable DB persistency for location entries

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

permissions params

#!ifdef WITH_IPAUTH
modparam("permissions", "db_url", DBURL)
modparam("permissions", "db_mode", 1)
#!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

presence params

#!ifdef WITH_PRESENCE
modparam("presence", "db_url", DBURL)
!endif

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

htable params

ip ban htable with autoexpire after 5 minutes

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

xmlrpc params

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

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 . Read more on Kamailio Call routing and Control

request_route { 
    # per request initial checks 
    route(REQINIT);

    #!ifdef WITH_WEBSOCKETS 
        if (nat_uac_test(64)) {     
            force_rport();     
            if (is_method("REGISTER")) {          
                fix_nated_register();     
            } else {         
                fix_nated_contact();         
                if (!add_contact_alias()) {  
                   xlog("L_ERR", "Error aliasing contact \n");             
                   sl_send_reply("400", "Bad Request");                    
                   exit;         
                }     
            } 
        } 
    #!endif

    # NAT detection 
    route(NATDETECT); 

    # CANCEL processing 
    if (is_method("CANCEL")) {     
        if (t_check_trans()) {         
            route(RELAY);     
        }     
        exit; 
    } 

    # handle requests within SIP dialogs 
    route(WITHINDLG); 

    ### only initial requests (no To tag) 
    # handle retransmissions 
    if(t_precheck_trans()) { 
        t_check_trans(); 
        exit; 
    } 
    t_check_trans(); 

    # authentication 
    route(AUTH); 

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

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

    # account only INVITEs 
    if (is_method("INVITE")) {     
        setflag(FLT_ACC); # do accounting 
    }

    # dispatch requests to foreign domains 
    route(SIPOUT); 

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

    # handle registrations 
    route(REGISTRAR); 

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

    # user location service 
    route(LOCATION); 
}

Wrapper for relaying requests

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

route[RELAY] {    
    if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {         
        if(!t_is_set("branch_route")) 
            t_on_branch("MANAGE_BRANCH");    
    }   
      
    if (is_method("INVITE|SUBSCRIBE|UPDATE")) {         
        
        if(!t_is_set("onreply_route"))
            t_on_reply("MANAGE_REPLY");    
        }   

        if (is_method("INVITE")) {        
            if(!t_is_set("failure_route")) 
                t_on_failure("MANAGE_FAILURE");     
        }    
        
        if (!t_relay()) {         
            sl_reply_error();     
        } 
    exit; 
}

Per SIP request initial checks

route[REQINIT] { 

if (!mf_process_maxfwd_header("10")) {     
   sl_send_reply("483","Too Many Hops");     
   exit; 
} 

if(is_method("OPTIONS") &amp;&amp; uri==myself &amp;&amp;; $rU==$null) {     
   sl_send_reply("200","Keepalive");     
   exit; 
} 

if(!sanity_check("1511", "7")) {     
  xlog("Malformed SIP message from $si:$sp\n");     
  exit; 
} 
}

Handle requests within SIP dialogs

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

route[WITHINDLG] {
    if (!has_totag()) return;
    if (has_totag()) {
        if (loose_route()) {
            #!ifdef WITH_WEBSOCKETS
            if ($du == "") {
                if (!handle_ruri_alias()) {
                    xlog("L_ERR", "Bad alias <$ru>\n");
                    sl_send_reply("400", "Bad Request");
                    exit;
                }
            }
            #!endif
         }
     exit;
     }

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

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

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

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

Handle SIP registrations

tbd

User location service

route[LOCATION] {

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

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

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

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

route(RELAY);
exit;
}

Presence processing

route[PRESENCE] {

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

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

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

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

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

IP authorization and user authentication

route[AUTH] {
#!ifdef WITH_AUTH

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

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

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

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

#!endif
return;
}

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

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

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 :

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

Proxying Media Streams via Kamailio’s RTP Proxy


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.

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

It is supported on jdk1.5 hence the system’s environment variables must match. Otherwise in later stages deploying applications throw class version error.


SIP VoIP system architecture basics


A VOIP/CPaaS solution is designed to accommodate the signalling and media both along with integration leads to various external endpoints such as various SIP phones ( desktop, softphones, webRTC ), telecom carriers, different VoIP networks providers, enterprise applications ( Skype, Microsoft Lync ), Trunks etc.

A sufficiently capable SIP platform should have

  1. Audio calls ( optionally video ) service using SIP gateways
  2. Media services (such as recording , conferencing, voicemail, and IVR )
  3. Messaging and presence ( could be using SIP SIMPLE, SMS , messahing service from third parties)
  4. Developing SIP based applications : Programmable services through standardized APIs and development of new modules
  5. NAT and DNS near-end and far-end NAT traversal for signalling and media flows
  6. Telemetry for Sessions , Registry, Location and lookup service
  7. CDR Processing and Billing : Backend for CDR and accounts ( can use Redis, Kafka , MySQL, PostgreSQL, Oracle, Radius, LDAP, Diameter)
  8. Serial and parallel forking, load balancing , proxying
  9. Cross platform and integration to External Telecommunication provider landscape
    • Interconnectivity with other IP multimedia systems, VoLTE ( optional interconnection with other types of communications networks as GSM or PSTN/ISDN).
    • support for VoIP signalling protocols (SIP, H,323, SCCP, MGCP, IAX) and telephony signalling protocols ( ISDN/SS7, FXS/FXO, Sigtran ) either internally via pluggable modules or externally via gateways .
Performnace factors :Security considerations :
High availability using redundant servers in standby
Load balancing
IPv4 and IPv6 network layer support
TCP , UDP , SCTP transport layer protocol support
DNS lookups and hop by hop connectvity
authentication, authorization, and accounting (AAA)
Digest authentication and credentials fetched from backend
Media Encryption
TLS and SRTP support
Topology hidding to prevent disclosing IP form internal components in via and route headers
Firewalls , blacklist, filters , peak detectors to prevent Dos and Ddos attacks

The article only outlines SIP system architecture  from 3 viewpoints :

  1. Infrastructure standpoint
  2. Vore voice engineering perspective
  3. External components required to run and system

Infrastructure Requirements

  • Data Centers with BCP ( Business Continuity Planning ) and DR ( Disaster Recovery )
  • Servers and Clusters for faster and parallel calculating
  • Virtualization
    VMs to make a distributed computing environment with HA ( high availability ) and DRS ( Distributed Resource Scheduling )
  • Storage
    SAN with built-in redundancy for the resiliency of data.
    WORM compliant NAS for storing voice archives over a retention period.
  • Racks, power supplies, battery backups, cages etc.
  • Networking
    DMZs ( Demilitarized Zones)  which are interfacing areas between internal servers in the green zone and outside network
    VLANs for segregation between tenants.
    Connectivity through the public Internet as well as through VPN or dedicated optical fibre network for security.
  • Firewall configuration
  • Load Balancer ( Layer 7 )
  • Reverse Proxies for the security of internal IPs and port
  • Security controls In compliance with ISO/IEC 27000 family – Information security management systems
  • PKI Infrastructure to manage digital certificates
  • Key management with HSM ( hardware security module )
  • truster CA ( Certificate Authority ) to issue publicly signed certificate for TLS ( Https, wss etc)
  • OWASP ( Open Web Application Security Project )  rules compliance

Integral Components of a VOIP SIP based architecture

  • Call Controller
  • Media Manager
  • Recording
  • Softclients
  • logs and PCAP archives
  • CDR generators
  • Session Borer Controllers ( SBCs)

A SIP server can be moulded to take up any role based on the libraries and programs that run on it such as gateway server, call manager, load balancer etc. This in turn defines its placement in overall VoIP communication architecture. For example
– stateless proxy servers are placed on the border,
– application and B2BUA server at the core

sip entities
SIP platform components

SIP Gateways

A SIP gateway is an application that interfaces a SIP network to a network utilising another signalling protocol. In terms of the SIP protocol, a gateway is just a special type of user agent, where the user agent acts on behalf of another protocol rather than a human. A gateway terminates the signalling path and can also terminate the media path .

sip gaeways
To PSTN for telephony inter-working
To H.323 for IP Telephony inter-working
Client – originates message
Server – responds to or forwards message

Logical SIP entities are:

  • User Agent Client (UAC): Initiates SIP requests  ….
  • User Agent Server (UAS): Returns SIP responses ….
  • Network Servers ….

Registrar Server

A registrar server accepts SIP REGISTER requests; all other requests receive a 501 Not Implemented response. The contact information from the request is then made available to other SIP servers within the same administrative domain, such as proxies and redirect servers. In a registration request, the To header field contains the name of the resource being registered, and the Contact header fields contain the contact or device URIs.

regsitrar server

Proxy Server

A SIP proxy server receives a SIP request from a user agent or another proxy and acts on behalf of the user agent in forwarding or responding to the request. Just as a router forwards IP packets at the IP layer, a SIP proxy forwards SIP messages at the application layer.

Typically proxy server ( inbound or outbound) have no media capabilities and ignore the SDP . They are mostly bypassed once dialog is established but can add a record-route .
A proxy server usually also has access to a database or a location service to aid it in processing the request (determining the next hop).

proxy server

 1. Stateless Proxy Server
A proxy server can be either stateless or stateful. A stateless proxy server processes each SIP request or response based solely on the message contents. Once the message has been parsed, processed, and forwarded or responded to, no information (such as dialog information) about the message is stored. A stateless proxy never retransmits a message, and does not use any SIP timers

2. Stateful Proxy Server
A stateful proxy server keeps track of requests and responses received in the past, and uses that information in processing future requests and responses. For example, a stateful proxy server starts a timer when a request is forwarded. If no response to the request is received within the timer period, the proxy will retransmit the request, relieving the user agent of this task.

  3 . Forking Proxy Server
A proxy server that receives an INVITE request, then forwards it to a number of locations at the same time, or forks the request. This forking proxy server keeps track of each of the outstanding requests and the response. This is useful if the location service or database lookup returns multiple possible locations for the called party that need to be tried.

Redirect Server

A redirect server is a type of SIP server that responds to, but does not forward, requests. Like a proxy server, a redirect server uses a database or location service to lookup a user. The location information, however, is sent back to the caller in a redirection class response (3xx), which, after the ACK, concludes the transaction. Contact header in response indicates where request should be tried .

redirect server

Application Server

The heart of all call routing setup. It loads and executes scripts for call handling at runtime and maintains transaction states and dialogs for all ongoing calls . Usually the one to rewrite SIP packets adding media relay servers, NAT . Also connects external services like Accounting , CDR , stats to calls .

Adding Media Management

Media processing is usually provided by media servers in accordance to the SIP signalling. Bridges, call recording, Voicemail, audio conferencing, and interactive voice response (IVR) are commomly used. Read more about Media Architecture here

RFC 6230 Media Control Channel Framework decribes framework and protocol for application deployment where the application programming logic and media processing are distributed.

Any one such service could be a combination of many smaller services within such as Voicemail is a combitional of prompt playback, runtime controls, Dual-Tone Multi-Frequency (DTMF) collection, and media recording. RFC 6231 Interactive Voice Response (IVR) Control Package for the Media Control Channel Framework.

DTMF( Dual tone Multi Frequency )

delivery options:

  • Inband –  With Inband digits are passed along just like the rest of your voice as normal audio tones with no special coding or markers using the same codec as your voice does and are generated by your phone.
  • Outband  – Incoming stream delivers DTMF signals out-of-audio using either SIP-INFO or RFC-2833 mechanism, independently of codecs – in this case, the DTMF signals are sent separately from the actual audio stream.

TTS ( Text to Speech )

 Alexa Text-to-Speech (TTS) + Amazon Polly

Ivona – multiple language text to speech converter with ssml scripts such as below

      <speak>
          <p>
              <s><prosody rate="slow">IVONA</prosody> means highest quality speech
              synthesis in various languages.</s>
              <s>It offers both male and female radio quality voices <break/> at a
              sampling rate of 22 kHz <break/> which makes the IVONA voices a
              perfect tool for professional use or individual needs.</s>
          </p>
      </speak>

check ivona status

service ivona-tts-http status
 tail -f /var/log/tts.log

Developing SIP based applications

Basic SIP methods

SIP defines basic methods such as INVITE, ACK and BYE which can pretty much handle simple call routing with some more advanced processoes too like call forwarding/redirection, call hold with optional Music on hold, call parking, forking, barge etc.

Extending SIP headers

Newer SIP headers defined by more updated SIP RFC’s contina INFO, PRACK, PUBLISH, SUBSCRIBY, NOTIFY, MESSAGE, REFER, UPDATE. But more methods or headers can be added to baseline SIP packets for customization specific to a particular service provider. In case where a unrecognized SIP header is found on a SIP proxy which it either does not suppirt or doesnt understand, it will simply forward it to the specified endpoint.

Call routing Scripts

Interfaces for programming SIP call routing include :
– Call Processing Language—SIP CPL,
– Common Gateway Interface—SIP CGI,
– SIP Servlets,
– Java API for Integrated Networks—JAIN APIs etc .

Some known SIP stacks :

SailFin – SIP servlet container uses GlassFish open source enterprise Application Server platform (GPLv2), obsolete since merger from Sun Java to Oracle.

Mobicents – supports both JSLEE 1.1 and SIP Servlets 1.1 (GPLv2)

Cipango – extension of SIP Servlets to the Jetty HTTP Servlet engine thus compliant with both SIP Servlets 1.1 and HTTP Servlets 2.5 standards.

WeSIP – SIP and HTTP ( J2EE) converged application server build on OpenSER SIP platform

Additionally SIP stacks are supported on almost all popular SIP programming lanaguges which can be imported as lib and used for building call routing scripts to be mounted on SIP servers or endpoints such as :

PJSIP in C

JSSIP Javascript

Sofia in kamailio , Freswitch

Some popular SIP server also have proprietary scripting language such as –
Asterisk Gateway Interface (AGI) , application interface for extending the dialplan with your functionality in the language you choose – PHP, Perl, C, Java, Unix Shell and others

SIP platform Development

  • audio calls ( optionally video )
  • media services such as conferencing, voicemail, and IVR,
  • messaging as IM and presence based on SIMPLE,
  • programmable services through standardized APIs and development of new modules
  • near-end and far-end NAT traversal for signalling and media flows
  • interconnectivity with other IP multimedia systems, VoLTE ( optional interconnection with other types of communications networks as GSM or PSTN/ISDN)
  • Registry, location and lookup service
  • Serial and parallel forking

A sufficiently capable SIP platform shoudl consist of following features :

Performance factors :

  • High availability using redundant servers in standby
  • Load balancing
  • IPv4 and IPv6 support

Security considerations :

  • digest authentication and credentials fetched from backend
  • Media Encryption
  • TLS and SRTP support
  • Topology hiding to prevent disclosng IP form internal components in via and route headers
  • Firewalls , blacklist, filters , peak detectors to prevent Dos and Ddos attacks .

Collecting and Processing PCAPS

  • VoIP monitor – network packet sniffer with commercial frontend for SIP RTP RTCP SKINNY(SCCP) MGCP WebRTC VoIP protocols

it uses a passive network sniffer (like tcpdump or wireshark) to analyse packets in realtime and transforms all SIP calls with associated RTP streams into database CDR record which is sent over the TCP to MySQL server (remote or local). If enabled saving SIP / RTP packets the sniffer stores each VoIP call into separate files in native pcap format (to local storage).

voip monitor
  • sngrep
  • tcpdump
  • custom made pcap capture and uploader

NAT and DNS

To adapt SIP to modern IP networks with inter network traversal ICE, far and near-end NAT traversal solutions are used. Network Address traversal is crtical to traffic flow between private public network and from behind firewalls and policy controlled networks
One can use any of the VOVIDA-based STUN server, mySTUN , TurnServer, reStund , CoTURN , NATH (PJSIP NAT Helper), ReTURN, or ice4j

Near-end NAT traversal

STUN (session traversal utilities for NAT) – UA itself detect presence of a NAT and learn the public IP address and port assigned using Nating. Then it replaces device local private IP address with it in the SIP and SDP headers. Implemented via STUN, TURN, and ICE.
limitations are that STUN doesnt work for symmetric NAT (single connection has a different mapping with a different/randomly generated port) and also with situations when there are multiple addresses of a end point.

TURN (traversal using relay around NAT) or STUN relay – UA learns the public IP address of the TURN server and asks it to relay incoming packets. Limitatiosn since it handled all incoming and outgong traffic, it must scale to meet traffic requirments and should not become the bottle neck junction or single point of failure.

ICE (interactive connectivity establishment) – UA gathers “candidates of communication” with priorities offered by the remote party. After this client pairs local candidates with received peer candidates and performs offer-answer negotiating by trying connectivity of all pairs, therefore maximising success. The types of candidates :
– host candidate who represents clients’ IP addresses,
– server reflexive candidate for the address that has been resolved from STUN
– and a relayed candidate for the address which has been allocated from a TURN relay by the client.

Far-end NAT traversal

UA is not concerned about NAT at all and communicated using its local IP port. The border controller implies a NAT handling components such as an application layer gateway (ALG) or universal plug and play (UPnP) etc which resolves the private and public network address mapping by act as a back to back user agent (B2BUA).
Far end NAT can also be enabled by deploying a public SIP server which performs media relay (RTP Proxy/Media proxy).

Limitations of this approach
(-) security risks as they are operating in the public network
(-) enabling reverse traffic from UAS to UAC behind NAT.

A keep-alive mechanism is used to keep NAT translations of communications between SIP endpoint and its serving SIP servers opened , so that this NAT translation can be reused for routing. It contains client-to-server “ping” keep-alive and corresponding server-to-client “pong” messages. The 2 keep-alive mechanisms: a CRLF keep-alive and a STUN keep-alive message exchange.

The 3 types of SIP URIs,

  • address of record (AOR)
  • fully qualified domain name (FQDN)
  • globally routable user agent (UA) URI
    SIP uniform resource identifiers (URIs) are identified based on DNS resolution since the URI after @ symbol contains hostname , port and protocl for the next hop.

Adding record route headers for locating the correct SIP server for a SIP message can be done by :
– DNS service record (DNS SRV)
– naming authority pointer (NAPTR) DNS resource record

Steps for SIP endpoints locating SIP server

  1. From SIP packet get the NAPTR record to get the protocl to be used
  2. Inspect SRV record to fetch port to use
  3. Inspect A/AAA record to get IPv4 or IPv6 addresses
    ref : RFC 3263 – Locating SIP Servers
    Can use BIND9 server for DNS resolution supports NAPTR/SRV, ENUM, DNSSEC, multidomains, and private trees or public trees.

CDR Processing and Billing

CDR store call detail records along with proof of call with tiemstamps, orignation, destination, duaration, rate etc. At the end of month or any other term, the aggregated CDR are cumulatively processed to generate the bill for a user. This heavy data stream needs to be accurately processed and this can be achived by using data-pipelines like AWS kinesis or Kafka eventstore.

The prime requirnment for the system is to handle enormous amount of call records data in relatime , cater to a number of producers and consumers.

For security the data is obfuscated into blob using base 64 encoding.

For good consistency only a single shard should be rsponsible to process one user account’s bill.

Data Streams for billing service

AWS Kinesis – Kinesis Data Streams is sued for for rapid and continuous data intake and aggregation. The type of data used can include IT infrastructure log data, application logs, social media, market data feeds, and web clickstream data. It supports data sharding (ie number of call records grouped) and uses a partition Key ( string MD5 hash) to determine which shard the record goes to. 

(+) This system can handle high volume of data in realtime and produce call uuid specfic reults which can be consumed by consumers waiting for the processed results

(-) If not consumed with a pre-specified time duration the processed results expire and are irretrivable . Self implement publisher to store teh processed reults from kisesis stream to data stores like Redis / RDBMS or other storge locations like s3 , dynamo DB. If pieline crashes during operation , data is lost

(-) Data stream should have low latency igesting contnous data from producer and presenting data to consumer.

Call Rate and Accounting

Generally data streams proecssing are used for crtical and voluminious service usage like for
– metering/billing
– server activity,
– website clicks,
– geo-location of devices, people, and physical goods

Call Rates are very crticial for billing and charging the calls . Any updates from the customer or carriers or individuals need to propagate automatically and quickly to avoid discrpencies and neagtive margins. CDRs need to be processed sequentially and incrementally on a record-by-record basis or over sliding time windows, and used for a wide variety of analytics including correlations, aggregations, filtering, and sampling.

To acheieve this the follow setup is ideal to use the new input rate sheet values via web UI console or POST API and propagate it quickly to main DB via AWS SQS which is a queing service and AWS lamda which is a serverless trigger based system . This ensures that any new input rates are updates in realtime and maintin fallback values in s3 bucket too

Call Rate and Accounting using task pipes , lambda serverless and qiueing service. Uses s3 buckets , AWS lambda, AWS SQS and AWS RDS.
Call Rate and Accounting using task pipes , lambda serverless and qiueing service

Cross platform and integration to External Telecommunication provider landscape

It is an advantage to plan for ahead for connection with IMS such as openIMS, support for Voip signalling protocols (SIP, H,323, SCCP, MGCP, IAX) and telephony signalling protocls ( ISDN/SS7, FXS/FXO, Sigtran ) either internally via pluggable modules or externally via gateways or for SIP trunking integration via OTT providers/ cloud telephony.

Adhere to Standard

The obvious starting milestone before making a full-scale carrier-grade, SIP-based VoIP system is to start by building a PBX for intra-enterprise communication. There are readily available solutions to make an IP telephony PBX Kamailio, FreeSWITCH, asterisk, Elastix, SipXecs. It is important to use the standard protocol and widely acceptable media formats and codecs to ensure interoperability and reduce compute and delay involved in protocol or media transcoding.

Database Integration

Need backend , cache , databse integration to npt only store routing rules with temporary varaible values but also aNeed backend, cache, database integration to not only store routing rules with temporary variable values but also account details, call records details, access control lists etc. Should therefore extend integration with text-based DB, Redis, MySQL, PostgreSQL, OpenLDAP, and OpenRadius.

Consistency of Call Records and duplicated charging records at various endpoints

In current Voip scenarios a call may be passing thorugh various telco providers , ISP and cloud telephony serviIn current VoIP scenarios, a call may be passing through various telco providers, ISP and cloud telephony service providers where each system maintains its own call records and billing. This in my opinion is duplication and can be avoided by sharing a consistent data store possible in the blockchain. This is an experimental idea that I have further explored in this article


There are other external components to setup a VOIP solution apart from Core voice Servers and gateways like the ones listed below, I will try to either add a detailed overall architecture diagram here or write about them in an seprate article. Keep watching this space for updates

  • Payment Gateways
  • Billing and Invoice
  • Fraud Prevention
  • Contacts Integration
  • Call Analytics
  • API services
  • Admin Module
  • Number Management ( DIDs ) and porting
  • Call Tracking
  • Single Sign On and User Account Management with Oauth and SAML
  • Dashboards and Reporting
  • Alert Management
  • Continuous Deployment
  • Automated Validation
  • Queue System
  • External cache

References :

SIP solutioning and architectures is a subsequent article after SIP introduction, which can be found here.

Read about VoIP/ OTT / Telecom Solution startup’s strategy for Building a scalable flexible SIP platform which includes :

  • Scalable and Flexible SIP platform building
  • Cluster SIP telephony Server for High Availability
  • Failure Recovery
  • Multi-tier cluster architecture
  • Role Abstraction / Micro-Service based architecture
  • Distributed Event management and Event-Driven architecture
  • Containerization
  • Autoscaling Cloud Servers
  • Open standards and Data Privacy
  • Flexibility for inter-working – NextGen911 , IMS , PSTN
  • security and Operational Efficiencies