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 https://github.com/altanai/opensipsexamples.
In the config of opensips load the file dispatcher.list with destination sets
modparam("dispatcher", "list_file", "/var/run/opensips/dispatcher.list")
proxies 2 sip:127.0.0.1:5080 2 sip:127.0.0.1:5082 gateways 1 sip:127.0.0.1:7070 1 sip:127.0.0.1:7072 1 sip:127.0.0.1:7074
or one can also load the sets from the database
modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database")
Tthe algorithm used to select the destination address.
“0” – hash over callid
“1” – hash over from uri.
“2” – hash over to uri.
“3” – hash over request-uri.
“4” – round-robin (next destination).
“5” – hash over authorization-username (Proxy-Authorization or “normal” authorization). If no username is found, round robin is used.
“6” – random (using rand()).
“7” – hash over the content of PVs string. Note: This works only when the parameter hash_pvar is set.
“X” – if the algorithm is not implemented, the first entry in set is chosen.
and the state of the destination address can be
“a”: active
“i”: inactive
“p”: probing
Load Balancer
Opensip can function as load balancer , distributing the load between different SIP Application servers .
example of gateway sets file in dbtext/diapatcher.list
id(int,auto) setid(int) destination(string) socket(string,null) state(int) weight(int) priority(int) attrs(string) description(string)
1:1:sip\:10.20.30.40\:5060:null:0:1:1:'carrier':'load balancer for OB'
2:2:sip\:10.50.60.70\:5060:null:0:1:1:'carrier':'Load balancer for IB'
Health Monitoring
Probing and pinging features in Opensips can detect whether gateways are responding or not . Threshold and probing mode can fine tune the behaviour.
OpenSIPS config file
sample config file for dispatcher module
debug=9 debug level (cmd line: -dddddddddd) fork=no log_stderror=yes (cmd line: -E) children=2 check_via=no (cmd. line: -v) dns=off (cmd. line: -r) rev_dns=off (cmd. line: -R) port=5060 mpath="/usr/local/lib/opensips/modules/" loadmodule "maxfwd.so" loadmodule "sl.so" loadmodule "dispatcher.so"
—————– setting module-specific parameters —————
dispatcher params
modparam("dispatcher", "list_file", "../etc/dispatcher.list") // modparam("dispatcher", "force_dst", 1) route{ if ( !mf_process_maxfwd_header("10") ) { sl_send_reply("483","To Many Hops"); drop(); }; ds_select_dst("2", "0"); forward(); // t_relay(); }
dbtext is an implementation for a simplified database engine based on text files. It can be used by OpenSIPS DB interface instead of other database module (like MySQL). It keeps everything in memory.
The db_text database system architecture contains
- a database is represented by a directory in the local file system. NOTE: when you use db_text in OpenSIPS, the database URL for modules must be the path to the directory where the table-files are located, prefixed by “text://”,
e.g., “text:///var/dbtext/opensips”. - a table is represented by a text file inside database directory.
Minimal OpenSIPS location db_text table definition
username(str) contact(str) expires(int) q(double) callid(str) cseq(int)
Minimal OpenSIPS subscriber db_text table example
username(str) password(str) ha1(str) domain(str) ha1b(str) suser:supasswd:xxx:alpha.org:xxx
This database interface don’t support the data insertion with default values. All such values specified in the database
template are ignored.
db_mode (integer)
Set caching mode (0 – default) or non-caching mode (1). In caching mode, data is loaded at startup. In non-caching mode, the module check every time a table is requested whether the correspondingfile on disk has changed, and if yes, will re-load table from file.
Set db_mode parameter
…
modparam(“db_text”, “db_mode”, 1)
…
loadmodule "/path/to/opensips/modules/db_text.so" modparam("module_name", "database_URL", "text:///path/to/dbtext/database ")
Subscriber and Location
Definition of ‘subscriber’ table (one line)
username(str) domain(str) password(str) first_name(str) last_name(str) phone(str) email_address(str) datetime_created(int) datetime_modified(int) confirmation(str) flag(str) sendnotification(str) greeting(str) ha1(str) ha1b(str) perms(str) allow_find(str) timezone(str,null) rpid(str,null)
Definition of ‘location’ and ‘aliases’ tables (one line)
username(str) domain(str,null) contact(str,null) received(str) expires(i nt,null) q(double,null) callid(str,null) cseq(int,null) last_modified(st r) flags(int) user_agent(str) socket(str)
Definition of ‘version’ table and sample records
table_name(str) table_version(int) subscriber:3 location:6 aliases:6
Configuration file using dbtext databse for oersistant storage . Also using auth
debug_mode=yes children=4 check_via=no # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) listen=udp:10.100.100.1:5060 loadmodule "modules/dbtext/dbtext.so" loadmodule "modules/sl/sl.so" loadmodule "modules/tm/tm.so" loadmodule "modules/rr/rr.so" loadmodule "modules/maxfwd/maxfwd.so" loadmodule "modules/usrloc/usrloc.so" loadmodule "modules/registrar/registrar.so" loadmodule "modules/textops/textops.so" loadmodule "modules/textops/mi_fifo.so" loadmodule "modules/auth/auth.so" loadmodule "modules/auth_db/auth_db.so" ----------------- setting module-specific parameters --------------- -- mi_fifo params -- modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") -- usrloc params -- modparam("usrloc", "db_mode", 2) modparam("usrloc|auth_db", "db_url", "text:///tmp/opensipsdb") modparam("auth_db", "calculate_ha1", 1) modparam("auth_db", "password_column", "password") modparam("auth_db", "user_column", "username") modparam("auth_db", "domain_column", "domain") route{ // initial sanity checks -- messages with max_forwards==0, or excessively long requests if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }; if ($ml &gt;= 65535 ) { sl_send_reply("513", "Message too big"); exit; }; // we record-route all messages -- to make sure that subsequent messages will go through this proxy; if (!$rm=="REGISTER") record_route(); <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"); route(1); exit; }; if (!is_myself("$rd")) { // mark routing logic in request append_hf("P-hint: outbound\r\n"); route(1); exit; }; //if the request is for other domain use UsrLoc if (is_myself("$rd")) { if ($rm=="REGISTER") { # digest authentication if (!www_authorize("", "subscriber")) { www_challenge("", "0"); exit; }; save("location"); exit; }; lookup("aliases"); if (!is_myself("$rd")) { append_hf("P-hint: outbound alias\r\n"); route(1); exit; }; # native SIP destinations are handled using our USRLOC DB if (!lookup("location")) { sl_send_reply("404", "Not Found"); exit; }; }; append_hf("P-hint: usrloc applied\r\n"); route(1);</code></pre> } route[1] { if (!t_relay()) { sl_reply_error(); }; }