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