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.

Combination of opensips working scenarios scripts with code is at

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

modparam("dispatcher", "list_file", "/var/run/opensips/dispatcher.list")
 2 sip:
 2 sip:
 1 sip:
 1 sip:
 1 sip:

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\:\:5060:null:0:1:1:'carrier':'load balancer for OB'
2:2:sip\:\: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)
 log_stderror=yes  (cmd line: -E)
 check_via=no      (cmd. line: -v)
 dns=off           (cmd. line: -r)
 rev_dns=off       (cmd. line: -R)
loadmodule ""
loadmodule ""
loadmodule ""

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

dispatcher params

 modparam("dispatcher", "list_file", "../etc/dispatcher.list")
 // modparam("dispatcher", "force_dst", 1)
 if ( !mf_process_maxfwd_header("10") )
 sl_send_reply("483","To Many Hops");
 ds_select_dst("2", "0");
 // 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)

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

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


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


loadmodule "modules/dbtext/"

loadmodule "modules/sl/"
loadmodule "modules/tm/"
loadmodule "modules/rr/"
loadmodule "modules/maxfwd/"
loadmodule "modules/usrloc/"
loadmodule "modules/registrar/"
loadmodule "modules/textops/"
loadmodule "modules/textops/"

loadmodule "modules/auth/"
loadmodule "modules/auth_db/"

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

// 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");
if ($ml >=  65535 ) {
sl_send_reply("513", "Message too big");

// we record-route all messages -- to make sure that subsequent messages will go through this proxy;
if (!$rm=="REGISTER") record_route();
<pre><code>// 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");

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

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


    if (!is_myself("$rd")) {
        append_hf("P-hint: outbound alias\r\n");

    # native SIP destinations are handled using our USRLOC DB
    if (!lookup("location")) {
        sl_send_reply("404", "Not Found");
append_hf("P-hint: usrloc applied\r\n");

if (!t_relay()) {