Skip to content

OpenSIPS Config Script Samples

Several OpenSIPS modules ship a complete, ready-to-run configuration script in their samples/ directory. This page collects those scripts in one place, grouped by module, so you can browse them side by side. Each script is taken straight from the module’s source tree; follow the module link for the full documentation of the functionality it demonstrates.

#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
# Valid for Opensips versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
# Valid for Opensips versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### DIALOG module with no DB support
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log", "cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
serialize_branches(1);
next_branches();
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
do_accounting("log","missed");
if (t_was_cancelled()) {
exit;
}
next_branches();
# if there are any more branches left for a new try,
# arm the failure route again
if ($rc != 2) {
t_on_failure("missed_call");
}
t_relay();
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
# Valid for Opensips versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
modparam("acc", "extra_fields", "log: src_ip; dst_ip")
#### DIALOG module with no DB support
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log", "cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
$acc_extra(src_ip) = $si; # source IP of the request
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
serialize_branches(1);
next_branches();
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
if ( $rs >= 200 )
$acc_extra(dst_ip) = $si;
}
failure_route[missed_call] {
do_accounting("log","missed");
if (t_was_cancelled()) {
exit;
}
next_branches();
# if there are any more branches left for a new try,
# arm the failure route again
if ($rc != 2) {
t_on_failure("missed_call");
}
t_relay();
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
# Valid for Opensips versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
modparam("acc", "extra_fields", "log: src_ip; dst_ip")
modparam("acc", "leg_fields", "log: caller; callee")
#### DIALOG module with no DB support
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log", "cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
$acc_extra(src_ip) = $si; # source IP of the request
$acc_leg(caller) = $fu;
$acc_leg(callee) = $ru;
# set a redirect URI if callee does not pick up
# it may be loaded from DB or any logic to get to it
$avp(redirect_uri) = "sip:charlie@my_domain.com";
route(lookup);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
route[lookup] {
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
xlog("User not found! sending negative reply!\n");
t_reply(404, "Not Found");
exit;
}
do_accounting("log","missed");
route(relay);
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
if ( $rs >= 200 )
$acc_extra(dst_ip) = $si;
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
if ( $avp(redirect_uri)!=NULL ) {
# set the new destination
$ru = $avp(redirect_uri);
# create a new call leg
acc_new_leg();
# new caller is the callee of the previous leg
$acc_leg(caller) = $(acc_leg(callee)[-2]);
# new callee is the new destination
$acc_leg(callee) = $ru;
t_on_failure("missed_call");
route(lookup);
exit;
}
}
#
# simple quick-start config script with dbtext
#
# ----------- global configuration parameters ------------------------
#debug_mode=yes
udp_workers=4
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
socket=udp:10.100.100.1:5060
# ------------------ module loading ----------------------------------
# use dbtext database
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"
# modules for digest authentication
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 --
# use dbtext database for persistent storage
modparam("usrloc", "working_mode_preset", "single-instance-sql-write-back")
modparam("usrloc|auth_db", "db_url", "text:///tmp/opensipsdb")
# -- auth params --
#
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "user_column", "username")
modparam("auth_db", "domain_column", "domain")
# ------------------------- request routing logic -------------------
# main routing logic
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 our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!$rm=="REGISTER") record_route();
# 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
# (in case, it does not work, use the following command
# with proper names and addresses in it)
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]
{
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}

OpenSIPS Config - Concurrent Call limitation with dialog profiles

Section titled “OpenSIPS Config - Concurrent Call limitation with dialog profiles”
#
# OpenSIPS Concurrent Call Limitation configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://docs.opensips.org/
# for an explanation of available statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog","db_mode",0)
modparam("dialog", "profiles_with_value", "caller")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (is_method("INVITE")) {
# keep dialog state
create_dialog("bye-on-timeout");
# create_dialog("B"); # for pre 4-0 versions
# account directly as CDRs
do_accounting("log","cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if( is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# limit to 5 concurrent calls per calling user
$var(caller) = "sip:"+$fU+"@"+$fd;
route( do_cc_limit, $var(caller), 5);
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
########################################################################
# This route is to be called for initial INVITEs, after
# the dialog was created
# Parameters:
# * the caller URI (string)
# * the limit (integer)
########################################################################
route[do_cc_limit]
{
# first add to the profile, just to avoid "test and set" false results
set_dlg_profile("caller", $param(1));
# do the actual test - see how many calls the user has so far
get_profile_size("caller", $param(1), $var(calls));
xlog("User $param(1) has $var(calls) ongoing calls so far, limit is $param(2)\n");
# check within limit
if( $var(calls)>$param(2) ) {
xlog("do_limit: user $param(1) exceeded number of calls [$var(calls)/$param(2)]\n");
send_reply(487, "Request Terminated: Channel limit exceeded\n");
exit;
# terminating this call will automatically remove the call from the profile
}
# call was added to the profile without exceeding
# the limit, so simply continue
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# sample config file for dispatcher module
#
socket= udp:*:5060
udp_workers = 2
check_via = off # (cmd. line: -v)
dns = off # (cmd. line: -r)
rev_dns = off # (cmd. line: -R)
# for more info: opensips -h
# ------------------ module loading ----------------------------------
mpath = "/usr/lib/x86_64-linux-gnu/opensips/modules"
loadmodule "maxfwd.so"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "db_mysql.so"
loadmodule "dispatcher.so"
loadmodule "proto_udp.so"
# ----------------- setting module-specific parameters ---------------
modparam("dispatcher", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
route {
if (!mf_process_maxfwd_header(10)) {
send_reply(483, "Too Many Hops");
exit;
}
if (!ds_select_dst(2, 0)) {
send_reply(503, "Service Unavailable");
exit;
}
t_relay();
}

Dynamic Routing Script - Routing to and from PSTN

Section titled “Dynamic Routing Script - Routing to and from PSTN”
#
# OpenSIPS Dynamic Routing (PSTN) configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
# This script, besides the SIP-2-SIP calling, shows how to route calls
# to and from PSTN Carriers (GW):
# * we do prefix based routing when calling to PSTN
# * DID based routing for calls from PSTN
# * GW failure detection and failover when routing to PSTN
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
alias="pstn.opensips.net" # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### DB MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0) # no DB
# we need the dialog module mainly for accouting with CDRs,
# not for dynamic routing.
#### GROUP module
loadmodule "group.so"
modparam("group", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
#### ALIAS DB module
loadmodule "alias_db.so"
modparam("alias_db", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
#### Dynamic ROUTING module
loadmodule "drouting.so"
modparam("drouting", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
# identify (IP based) and deal with calls from carriers
if (is_from_gw()) {
# mark call as coming from PSTN carrier
setflag("FROM_PSTN");
# set as RURI domain something of ours, just to be sure
# it will be considered local
$rd = "pstn.opensips.net";
} if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
create_dialog();
do_accounting("log", "cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# first, if DID, normalize the dial out prefix, converting to E.164
if ($rU =~ "\+[1-9][0-9]{4,}") {
strip(1);
} else
if ($rU =~ "00[1-9][0-9]{4,}") {
strip(2);
} else
if ($rU =~ "011[1-9][0-9]{4,}") {
strip(3);
}
# you can also use dialplan module for the above normalization
# if the call comes from a PSTN carrier, use aliases to translate
# the DID to one of our users
if ( isflagset("FROM_PSTN") ) {
if (!alias_db_lookup("dbaliases", "d")) {
send_reply( 404, "DID not found");
exit;
};
# now we have in RURI one of our SIP users, so continue
# normal routing to a local registered user
} else
# is it a DID dialled ? if so, route to PSTN carriers
if ($rU =~ "[1-9][0-9]{4,}") {
# first, does the user have the permission to call to PSTN ?
# here we use the groups module for such check, but ideally you
# should add some authentication for the users ;)
if ( !db_is_user_in("$fu", "pstn")) {
send_reply( 403, "Forbidden pstn");
exit;
}
# OK, continue with prefix based routing to pstn over DR group 1
if (!do_routing(1)) {
send_reply( 404, "Destination not found");
exit;
}
t_on_failure("gw_failover");
t_relay();
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
failure_route[gw_failover] {
if (t_was_cancelled()) {
exit;
}
# let's see if we should do GW failover and try another destination
# was it a GW failure ? (we do not want to do failover
# if it was a call setup failure, so we look for 500 and 600
# class replied and for local timeouts)
if ( t_check_status("5[0-9][0-9]") ||
(t_check_status("408") && t_local_replied("all")) ) {
# this is a case for failover
xlog("REPORT: GW destination $ru failed with code $T_reply_code\n");
# mark failed GW as disabled
dr_disable();
# try to see if there is any other GW left to try
if ( use_next_gw() ) {
xlog("New selected GW is: $ru\n");
t_on_failure("gw_failover");
t_relay();
} else {
t_reply(500,"No service");
}
exit;
}
}

This configuration file presents the usage of the event_rabbitmq module. In this scenario, a message is sent to a RabbitMQ server everytime OpenSIPS receives a MESSAGE request. The parameters passed to the server are the R-URI username and the message body.

loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri.so"
loadmodule "acc.so"
loadmodule "event_rabbitmq.so"
startup_route {
if (!subscribe_event("E_SIP_MESSAGE", "rabbitmq:127.0.0.1/sipmsg")) {
xlog("L_ERR","cannot the RabbitMQ server to the E_SIP_MESSAGE event\n");
}
}
route{
if (!mf_process_maxfwd_header(10)) {
sl_send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
if (loose_route()) {
if (is_method("INVITE")) {
record_route();
}
route(1);
} else {
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
t_relay();
exit;
} else {
exit;
}
}
sl_send_reply(404,"Not here");
}
exit;
}
if (is_method("CANCEL"))
{
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
sl_send_reply(403,"Preload Route denied");
exit;
}
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (!is_myself("$rd"))
{
append_hf("P-hint: outbound\r\n");
route(1);
}
if (is_method("PUBLISH"))
{
sl_send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER"))
{
if (!save("location"))
sl_reply_error();
exit;
}
if ($rU==NULL) {
sl_send_reply(484,"Address Incomplete");
exit;
}
if (is_method("MESSAGE")) {
$avp(attrs) = "user";
$avp(vals) = $rU;
$avp(attrs) = "msg";
$avp(vals) = $rb;
if (!raise_event("E_SIP_MESSAGE", $avp(attrs), $avp(vals)))
xlog("L_ERR", "cannot raise E_SIP_MESSAGE event\n");
}
if (!lookup("location", "method-filtering")) {
switch ($retcode) {
case -1:
case -3:
t_newtran();
t_reply(404, "Not Found");
exit;
case -2:
sl_send_reply(405, "Method Not Allowed");
exit;
}
}
route(1);
}
route[1] {
if (is_method("INVITE")) {
t_on_failure("1");
}
if (!t_relay()) {
sl_reply_error();
};
exit;
}
failure_route[1] {
if (t_was_cancelled()) {
exit;
}
}

This config is based on the simple SIP-to-SIP scenario. In addition to that we have Push Notification support for the calls to users. For the incoming calls (to users) we are using the exec module to run (in async mode) an external script for PN triggering. For this purpose, for each local user, we may store (in subscriber table) an optional PN token - this will be passed to the PN triggering script.

#
# OpenSIPS EXEC (for PN) configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
# We start from the default SIP 2 SIP calling setup. What we do here with the
# calls to user is to trigger, vie async exec, an external script for
# the PN firing.
# For this purpose we consider an extra column in the subscriber table:
# * "pn_token", default null, string(129) - the PN identifier of the user
# Note that we have no authentication or authorization here,
# this is just an example
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### DB MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0) # no DB
# we need the dialog module mainly for accouting with CDRs,
# not for the call forking
#### SQL OPerationS module
loadmodule "sqlops.so"
modparam("sqlops","db_url","mysql://opensips:opensipsrw@localhost/opensips")
#### EVENT_ROUTING module
loadmodule "event_routing.so"
#### EXEC module
loadmodule "exec.so"
modparam("exec", "time_to_kill", 20)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
create_dialog();
do_accounting("log", "cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# check if PN triggering is enabled
# we have one or multiple registrations of SIP devices
xlog("[$ci] checking PN token for user $ru\n");
# now check for the mobile DID in the subscriber table
sql_query("select pn_token from subscriber where username='$rU' and domain='$rd' ", "$avp(pn_token)");
if ($rc<0 || $avp(pn_token)==NULL) {
xlog("unable to find a PN token for the user $ru\n");
} else {
# prepare for handle new registrations (due to the PN)
t_wait_for_new_branches();
# subscribe to new contact registration event, but for our callee only
$avp(pn_filter) = "aor=" + $rU + "@" + $rd;
notify_on_event("E_UL_CONTACT_INSERT", $avp(pn_filter), "pn_inject_branch", 30);
# now fire the external PN script ; do it fully async, so there
# is no waiting here for the execution of the external script
launch( exec("my_pn_script.sh $avp(pn_token)"), pn_report, "$ru" );
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
# this t_rely will take all the branches we collected so
# far (SIP and PSTN) and send them out in the same time
route(relay);
}
route[pn_report] {
if ($rc < 0)
xlog("PN triggering for user <$param(1)> failed\n");
else
xlog("PN triggering for user <$param(1)> was successful\n");
}
route[pn_inject_branch]
{
xlog("[xxx] user $avp(aor) registered the a new contact $avp(uri)/$avp(received), attr=[$avp(attr)], injecting it in transaction\n");
# take the contact described by the E_UL_CONTACT_INSERT
# event and inject it as a new branch into the original transaction
t_inject_branches("event");
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
xlog("[$ci] t_relay to $avp(callee) with branches [$(msg.branch.uri[*])]\n");
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("[$ci] new branch $T_branch_idx going to $ru/$du, is_pstn = $tm.branch.flag(pstn)\n");
}
onreply_route[handle_nat] {
xlog("incoming $rs/$rr reply received on branch $T_branch_idx\n");
}
failure_route[missed_call] {
xlog("[$ci] final reply $T_reply_code on branch $T_branch_idx, is_pstn = $tm.branch.flag(pstn)\n");
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS Load-Balancer configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://docs.opensips.org/
# for an explanation of available statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "db_mode", 1)
modparam("dialog", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
#### LOAD BALANCER module
loadmodule "load_balancer.so"
modparam("load_balancer", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
# ping every 30 secs the failed destinations
modparam("load_balancer", "probing_interval", 30)
modparam("load_balancer", "probing_from", "sip:pinger@127.0.0.1:5060")
# consider positive ping reply the 404
modparam("load_balancer", "probing_reply_codes", "404")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
# from now on we have only the initial requests
if (!is_method("INVITE")) {
send_reply(405,"Method Not Allowed");
exit;
}
# initial request
record_route();
# not really necessary to create the dialog from script (as the
# LB functions will do this for us automatically), but we do it
# if we want to pass some flags to dialog (pinging, bye, etc)
create_dialog("bye-on-timeout");
#create_dialog("B"); #for pre 4.0 versions
# check the direction of call
if ( lb_is_destination($si, $sp, 1) ) {
# call comes from our cluster, so it is an PSNT inbound call
# mark it as load on the corresponding destination
lb_count_call($si, $sp, 1, "pstn");
# and route is to our main sip server to send call to end user
$du = "sip:PROXY_IP:PROXY_PORT"; # REPLACE here with right values
t_relay();
exit;
} else
if ($si!="PROXY_IP" /*|| $sp!=PROXY_PORT*/) {
# call not coming neither from media server, nor from the core proxy,
# so it should be declined
send_reply( 403, "Forbidden");
exit;
}
# here we have only initial calls from core proxy, calls to be balanced
# to the media servers
# detect resources and do balancing
if ($rU=~"^1") {
# looks like a Conference call
$var(resources) = "conf";
} else if ($rU=~"^2") {
# looks like a VoiceMail call
$var(resources) = "vm";
} else if ($rU=~"^[0-9]+$") {
# PSTN call, but the GWs supports only G711
# for calls without G711, transcoding will be used on the GW
if ( !codec_exists("G711") ) {
$var(resources) = "transc;pstn";
} else {
$var(resources) = "pstn";
}
} else {
send_reply(404,"Destination not found");
exit;
}
# now do the LB with the discovered resources
# LB function returns negative if no suitable destination (for
# requested resources) is found, or if all destinations are full
if (!lb_start(1,$var(resources))) {
send_reply(500,"Service full");
exit;
}
xlog("Selected destination is: $du\n");
# send it out
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("failed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[failed_call] {
if (t_was_cancelled()) {
exit;
}
# let's see if we should do LB failover and try another destination
# was a destination failure ? (we do not want to do failover
# if it was a call setup failure, so we look for 500 and 600
# class replied and for local timeouts)
if ( t_check_status("5[0-9][0-9]") ||
(t_check_status("408") && t_local_replied("all")) ) {
# this is a case for failover
xlog("REPORT: LB destination $du failed with code $T_reply_code\n");
# mark failed destination as disabled
lb_disable_dst();
if ( lb_next() ) {
t_on_failure("failed_call");
xlog("New selected destination is: $du\n");
t_relay();
} else {
t_reply(500,"No capacity left");
}
exit;
}
}
#
# OpenSIPS Message SILO configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic msilo configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### DB MYSQL module
loadmodule "db_mysql.so"
#### Message SILO module
loadmodule "msilo.so"
modparam("msilo","db_url","mysql://opensips:opensipsrw@localhost/opensips")
# notifications to senders
modparam("msilo","offline_message","User $rU@$rd is offline, your message was stored for later delivery")
modparam("msilo","contact_hdr","Contact: message_handler@127.0.0.1:5060;msilo=yes\r\n")
modparam("msilo","content_type_hdr", "Content-Type: text/plain\r\n")
modparam("msilo","from_address","sip:message_handler@127.0.0.1")
# no reminders
modparam("msilo", "send_time", 0)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
else {
xlog("successful REGISTER -> dumping MSILO for $tu\n");
# MSILO - dumping user's offline messages
if (m_dump($tu)) {
xlog("MSILO: offline messages dumped - if they were\n");
} else {
xlog("MSILO: no offline messages dumped\n");
}
}
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# we may need (for msilo) the calle AOR later ; store it as RURI will
# be changed by lookup(location) with the registered contact
$avp(callee_uri) = $ru;
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
# store it if a MESSAGE, for later delivery
if (is_method("MESSAGE")) {
xlog("MESSAGE received for $ru-> storing using MSILO\n");
t_newtran();
# MSILO - storing as offline message
if (m_store("$ru")) {
xlog("MSILO: offline message stored\n");
t_reply(202, "Accepted");
}else{
xlog("MSILO: offline message NOT stored\n");
t_reply(503, "Service Unavailable");
}
exit;
}
t_reply(486, "Unavailable");
exit;
}
# when sending a MESSAGE to the user, use a different failure route
# in order to see if the MESSAGE was accepted or not
# TAKE CARE not to conflict with other failure_route setting
if (is_method("MESSAGE")) {
t_on_failure("msg_failed");
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
failure_route[msg_failed] {
# this is armed only for MESSAGEs to users
xlog("MSILO: the callee UA doesn't support MESSAGEs, replied with $T_reply_code \n");
if (m_store( $avp(callee_uri) )){
xlog("MSILO: offline message stored for $avp(callee_uri)\n");
t_reply(202, "Accepted");
}else{
xlog("MSILO: offline message NOT stored for $avp(callee_uri)\n");
t_reply(503, "Service Unavailable");
};
}
local_route {
# here we can see the MESSAGE requests generated by MSILO
# NOTE : these MESSAGEs go directly from OpenSIPS to the user
if (is_method("MESSAGE")) {
xlog("MSILO: stored message being sent to callee $tu\n");
}
}

OpenSIPS Config - Simple quick-start config script with nathelper support

Section titled “OpenSIPS Config - Simple quick-start config script with nathelper support”
#
# simple quick-start config script including nathelper support
# This default script includes nathelper support. To make it work
# you will also have to install Maxim's RTP proxy. The proxy is enforced
# if one of the parties is behind a NAT.
#
# If you have an endpoing in the public internet which is known to
# support symmetric RTP (Cisco PSTN gateway or voicemail, for example),
# then you don't have to force RTP proxy. If you don't want to enforce
# RTP proxy for some destinations than simply use t_relay() instead of
# route(1)
#
# Sections marked with !! Nathelper contain modifications for nathelper
#
# NOTE !! This config is EXPERIMENTAL !
#
# ----------- global configuration parameters ------------------------
log_level=3 # logging level (cmd line: -dddddddddd)
stderror_enabled=no
syslog_enabled=yes
/* Uncomment these lines to enter debugging mode */
#debug_mode=yes
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
udp_workers=4
socket= udp:127.0.0.1:5060
# ------------------ module loading ----------------------------------
#set module path
mpath="/usr/local/lib/opensips/modules/"
# Uncomment this if you want to use SQL database
#loadmodule "db_mysql.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "signaling.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "sipmsgops.so"
loadmodule "mi_fifo.so"
# Uncomment this if you want digest authentication
# db_mysql.so must be loaded !
#loadmodule "auth.so"
#loadmodule "auth_db.so"
# !! Nathelper
loadmodule "nathelper.so"
loadmodule "rtpproxy.so"
loadmodule "proto_udp.so"
# ----------------- setting module-specific parameters ---------------
# -- mi_fifo params --
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
# -- usrloc params --
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
# Uncomment this if you want to use SQL database
# for persistent storage and comment the previous line
#modparam("usrloc", "working_mode_preset", "single-instance-sql-write-back")
# -- auth params --
# Uncomment if you are using auth module
#modparam("auth_db", "calculate_ha1", yes)
#
# If you set "calculate_ha1" parameter to yes (which true in this config),
# uncomment also the following parameter)
#modparam("auth_db", "password_column", "password")
# !! Nathelper
modparam("usrloc","nat_bflag", "NAT")
modparam("nathelper","sipping_bflag", "SIP_PING")
modparam("nathelper", "ping_nated_only", 1) # Ping only clients behind NAT
# ------------------------- request routing logic -------------------
# main routing logic
route{
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
# !! Nathelper
# Special handling for NATed clients; first, NAT test is
# executed: it looks for via!=received and RFC1918 addresses
# in Contact (may fail if line-folding is used); also,
# the received test should, if completed, should check all
# vias for rpesence of received
if (nat_uac_test("diff-ip-src-via,private-contact")) {
# Allow RR-ed requests, as these may indicate that
# a NAT-enabled proxy takes care of it; unless it is
# a REGISTER
if (is_method("REGISTER") || !is_present_hf("Record-Route")) {
xlog("Someone trying to register from private IP, rewriting\n");
# This will work only for user agents that support symmetric
# communication. We tested quite many of them and majority is
# smart enough to be symmetric. In some phones it takes a
# configuration option. With Cisco 7960, it is called
# NAT_Enable=Yes, with kphone it is called "symmetric media" and
# "symmetric signalling".
# Rewrite contact with source IP of signalling
fix_nated_contact();
if ( is_method("INVITE") ) {
fix_nated_sdp("add-dir-active"); # Add direction=active to SDP
};
force_rport(); # Add rport parameter to topmost Via
setbflag("NAT"); # Mark as NATed
# if you want sip nat pinging
setbflag("SIP_PING");
};
};
# 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(relay);
exit;
};
# we record-route all messages -- to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!is_method("REGISTER"))
record_route();
if (!is_myself("$rd")) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
route(relay);
exit;
};
# if the request is for other domain use UsrLoc
# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (is_myself("$rd")) {
if (is_method("REGISTER")) {
# Uncomment this if you want to use digest authentication
#if (!www_authorize("siphub.org", "subscriber")) {
# www_challenge("siphub.org", "0");
# return;
#};
save("location");
exit;
};
lookup("aliases");
if (!is_myself("$rd")) {
append_hf("P-hint: outbound alias\r\n");
route(relay);
exit;
};
# native SIP destinations are handled using our USRLOC DB
if (!lookup("location")) {
send_reply(404, "Not Found");
exit;
};
};
append_hf("P-hint: usrloc applied\r\n");
route(relay);
}
route[relay]
{
# !! Nathelper
if ( $(rd{ip.isprivate})==1 && !is_present_hf("Route") ) {
send_reply(479, "We don't forward to private IP addresses");
exit;
};
# if client or server know to be behind a NAT, enable relay
if (isbflagset("NAT")) {
rtpproxy_offer();
};
# NAT processing of replies; apply to all transactions (for example,
# re-INVITEs from public to private UA are hard to identify as
# NATed at the moment of request processing); look at replies
t_on_reply("reply_handler");
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}
# !! Nathelper
onreply_route[reply_handler] {
# NATed transaction ?
if (isbflagset("NAT") && $rs =~ "(183)|2[0-9][0-9]") {
fix_nated_contact();
rtpproxy_answer();
# otherwise, is it a transaction behind a NAT and we did not
# know at time of request processing ? (RFC1918 contacts)
} else if (nat_uac_test("private-contact")) {
fix_nated_contact();
};
}

OpenSIPS Config - Simple usage of PI_HTTP module

Section titled “OpenSIPS Config - Simple usage of PI_HTTP module”
#
# this example shows use of opensips's provisioning interface
#
# ------------------ module loading ----------------------------------
#set module path
mpath="/usr/local/lib64/opensips/modules/"
#### DB MYSQL module
loadmodule "db_mysql.so"
#### HTTPD module
loadmodule "httpd.so"
modparam("httpd", "port", 8888)
#### MI HTTP module
# this is to allow HTML interface for the MI commands
loadmodule "mi_http.so"
#### Provioning Interface HTTP module
loadmodule "pi_http.so"
modparam("pi_http", "framework", "/usr/local/share/opensips/pi_http/pi_framework.xml")
# ------------------------- request routing logic -------------------
# main routing logic
# (not relevant here, we just want to show the provioning HTML interface)
route{
exit;
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
# Valid for Opensips versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_xml.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("presence", "fallback2db", 0)
modparam("presence_xml", "force_active", 1) # do not check XCAP rules
#### XCAP module
loadmodule "xcap.so"
modparam("xcap", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
` if (is_method("SUBSCRIBE") && is_myself("$rd")) {
# in-dialog subscribe requests
route(handle_presence);
exit;
}
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
if( is_method("PUBLISH|SUBSCRIBE")) {
route(handle_presence);
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
# Presence route
route[handle_presence]
{
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(is_method("PUBLISH")) {
handle_publish();
} else
if( is_method("SUBSCRIBE")) {
handle_subscribe();
}
exit;
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
# Valid for Opensips versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### HTTPD module
loadmodule "httpd.so"
# be careful to set the same port in OpenXCAP configuration file
modparam("httpd", "port", 8888)
#### MI_XMLRPC module
loadmodule "mi_xmlrpc.so"
# be careful to set the same path in OpenXCAP configuration file
modparam("mi_xmlrpc", "http_root", "RPC2")
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_xml.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("presence", "fallback2db", 0)
modparam("presence_xml", "force_active", 0) # check XCAP rules
#### XCAP module
loadmodule "xcap.so"
modparam("xcap", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("xcap", "integrated_xcap_server", 1) # use local DB for XCAP rules
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
` if (is_method("SUBSCRIBE") && is_myself("$rd")) {
# in-dialog subscribe requests
route(handle_presence);
exit;
}
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
if( is_method("PUBLISH|SUBSCRIBE")) {
route(handle_presence);
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
# Presence route
route[handle_presence]
{
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(is_method("PUBLISH")) {
handle_publish();
} else
if( is_method("SUBSCRIBE")) {
handle_subscribe();
}
exit;
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the Core CookBook at:
# http://www.opensips.org/Resources/Cookbooks
# for an explanation of possible statements, functions and parameters.
#
####### Global Parameters #########
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
auto_aliases=no
# Set up listeners
socket=ws:127.0.0.1:8080
socket=wss:127.0.0.1:443
socket=tls:127.0.0.1:5061
socket=udp:127.0.0.1:5060
####### Modules Section ########
# set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### DIALOG module
loadmodule "dialog.so"
#### REGISTRAR module
loadmodule "registrar.so"
#### RTP_RELAY protocol
loadmodule "rtp_relay.so"
#### RTPengine protocol
loadmodule "rtpengine.so"
modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:60000")
#### Nathelper protocol
loadmodule "nathelper.so"
modparam("registrar|nathelper", "received_avp", "$avp(rcv)")
#### UDP protocol
loadmodule "proto_udp.so"
#### TLS protocol
loadmodule "tls_wolfssl.so"
loadmodule "tls_mgm.so"
loadmodule "proto_tls.so"
#### WebSocket and WebSocketSecure protocol
loadmodule "proto_ws.so"
loadmodule "proto_wss.so"
# Certificate management
modparam("tls_mgm", "server_domain", "default")
modparam("tls_mgm", "match_ip_address", "[default]*")
modparam("tls_mgm", "certificate", "[default]/etc/letsencrypt/live/acme.com/fullchain.pem")
modparam("tls_mgm", "private_key", "[default]/etc/letsencrypt/live/acme.com/privkey.pem")
modparam("tls_mgm", "verify_cert", "[default]0")
modparam("tls_mgm", "require_cert", "[default]0")
####### Routing Logic ########
# main request routing logic
route {
if (!mf_process_maxfwd_header(10)) {
send_reply(483, "Too Many Hops");
exit;
}
if (has_totag()) {
# sequential requests within a dialog should
# take the path determined by record-routing
if (loose_route()) {
if (is_method("INVITE")) {
# even if in most of the cases is useless, do RR for
# re-INVITEs also, as some buggy clients do change route set
# during the dialog.
record_route();
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
} else {
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# non loose-route, but stateful ACK; must be an ACK after
# a 487 or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ->
# ignore and discard
exit;
}
}
send_reply(404, "Not here");
}
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
if (!is_method("REGISTER")) {
if (!is_myself("$fd")) {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403, "Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403, "Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
# check if the clients are using WebSockets or WebSocketSecure
if ($socket_in(proto) == "WS" || $socket_in(proto) == "WSS")
setflag("SRC_WS");
# consider the client is behind NAT - always fix the contact
fix_nated_contact();
if (is_method("REGISTER")) {
# indicate that the client supports DTLS
# so we know when he is called
if (isflagset("SRC_WS"))
setbflag("DST_WS");
fix_nated_register();
if (!save("location"))
send_reply(500, "Registration failed");
exit;
}
if ($rU == NULL) {
# request with no Username in RURI
send_reply(484, "Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location", "method-filtering")) {
t_newtran();
t_reply(404, "Not Found");
exit;
}
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("handle_nat");
t_on_reply("handle_nat");
}
if (!t_relay()) {
send_reply(500, "Internal Error");
}
exit;
}
branch_route[handle_nat] {
if (!is_method("INVITE") || !has_body("application/sdp"))
return;
if (isbflagset("DST_WS"))
$rtp_relay(type) = "UDP/TLS/RTP/SAVPF ICE=force";
else
$rtp_relay(type) = "RTP/AVP ICE=remove";
if (isflagset("SRC_WS"))
$rtp_relay_peer(type) = "UDP/TLS/RTP/SAVPF ICE=force";
else
$rtp_relay_peer(type) = "RTP/AVP ICE=remove";
if (!has_totag())
rtp_relay_engage("rtpengine");
}
onreply_route[handle_nat] {
fix_nated_contact();
if (!has_body("application/sdp"))
return;
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://docs.opensips.org/
# for an explanation of available statements, functions and parameters.
#
# Valid for OpenSIPS versions 2.3 and above
# Bridge Line Appearance( event:dialog;sla)
# BLA + SIP Presence Server
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog","db_mode",0)
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_xml.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("presence", "fallback2db", 0)
modparam("presence_xml", "force_active", 1) # do not check XCAP rules
#### XCAP module
loadmodule "xcap.so"
modparam("xcap", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### PUA modules
loadmodule "pua.so"
loadmodule "pua_bla.so"
modparam("pua","db_url","mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
# the address of the Presence Server where the PUA module should send the
# PUBLISH requests - as we have the PA in the same instance, we send these
# PUBLISH requests to ourselves - be sure and keep this in sync with the
# OpenSIPS socket above !!!
modparam("pua_bla", "server_address", "sip:127.0.0.1:5060 ")
modparam("pua_bla", "default_domain", "opensips.org")
modparam("pua_bla", "header_name", "Sender")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
` if (is_method("SUBSCRIBE") && is_myself("$rd")) {
# in-dialog subscribe requests
route(handle_presence);
exit;
}
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# handle BLA Notifications
if (is_method("NOTIFY") && $hdr(event)=="dialog;sla") {
bla_handle_notify();
t_reply(200, "OK");
exit;
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (is_method("INVITE")) {
# keep dialog state
create_dialog();
# account directly as CDRs
do_accounting("log","cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if( is_method("PUBLISH|SUBSCRIBE")) {
route(handle_presence);
}
if (is_method("REGISTER")) {
if ($hdr(User-Agent)=~ "PolycomSoundPointIP")
bla_set_flag();
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
# Presence route
route[handle_presence]
{
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(is_method("PUBLISH")) {
# if we have a Sender header, use it to seed
# the sender value
handle_publish("$hdr(Sender)");
} else
if( is_method("SUBSCRIBE")) {
handle_subscribe();
}
exit;
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}

OpenSIPS Config - Basic PUA dialoginfo usage

Section titled “OpenSIPS Config - Basic PUA dialoginfo usage”
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://docs.opensips.org/
# for an explanation of available statements, functions and parameters.
#
# Valid for OpenSIPS versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog","db_mode",0)
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_xml.so"
loadmodule "presence_dialoginfo.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("presence", "fallback2db", 0)
modparam("presence_xml", "force_active", 1) # do not check XCAP rules
#### XCAP module
loadmodule "xcap.so"
modparam("xcap", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### PUA modules
loadmodule "pua.so"
loadmodule "pua_dialoginfo.so"
modparam("pua","db_url","mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
# the address of the Presence Server where the PUA module should send the
# PUBLISH requests - as we have the PA in the same instance, we send these
# PUBLISH requests to ourselves - be sure and keep this in sync with the
# OpenSIPS socket above !!!
modparam("pua_dialoginfo", "presence_server", "sip:127.0.0.1:5060 ")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
` if (is_method("SUBSCRIBE") && is_myself("$rd")) {
# in-dialog subscribe requests
route(handle_presence);
exit;
}
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (is_method("INVITE")) {
# keep dialog state
create_dialog();
# publish BLF for caller if local
if (is_myself("$fd"))
dialoginfo_set("A");
# account directly as CDRs
do_accounting("log","cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if( is_method("PUBLISH|SUBSCRIBE")) {
route(handle_presence);
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
if (is_method("INVITE")) {
# publish BLF for callee as local
dialoginfo_set("B");
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
# Presence route
route[handle_presence]
{
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(is_method("PUBLISH")) {
handle_publish();
} else
if( is_method("SUBSCRIBE")) {
handle_subscribe();
}
exit;
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://docs.opensips.org/
# for an explanation of available statements, functions and parameters.
#
# Valid for OpenSIPS versions 2.3 and above
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/popensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog","db_mode",0)
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_xml.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("presence", "fallback2db", 0)
modparam("presence_xml", "force_active", 1) # do not check XCAP rules
#### XCAP module
loadmodule "xcap.so"
modparam("xcap", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### PUA modules
loadmodule "pua.so"
loadmodule "pua_usrloc.so"
modparam("pua","db_url","mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
# the address of the Presence Server where the PUA module should send the
# PUBLISH requests - as we have the PA in the same instance, we send these
# PUBLISH requests to ourselves - be sure and keep this in sync with the
# OpenSIPS socket above !!!
modparam("pua_usrloc", "presence_server", "sip:127.0.0.1:5060 ")
modparam("pua_usrloc", "default_domain", "opensips.org")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
` if (is_method("SUBSCRIBE") && is_myself("$rd")) {
# in-dialog subscribe requests
route(handle_presence);
exit;
}
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (is_method("INVITE")) {
# keep dialog state
create_dialog();
# account directly as CDRs
do_accounting("log","cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if( is_method("PUBLISH|SUBSCRIBE")) {
route(handle_presence);
}
if (is_method("REGISTER")) {
# make pua_usrloc send PUBLISH for phones which do not support
# presence; do filter after User-Agent header
if ( $hdr("User-Agent")=~"Old phone" )
pua_set_publish();
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
# Presence route
route[handle_presence]
{
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(is_method("PUBLISH")) {
handle_publish();
} else
if( is_method("SUBSCRIBE")) {
handle_subscribe();
}
exit;
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://docs.opensips.org/
# for an explanation of available statements, functions and parameters.
#
# Valid for OpenSIPS versions 2.3 and above
# SIP to XMPP Gateway + SIP Presence Server
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog","db_mode",0)
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_xml.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("presence", "fallback2db", 0)
modparam("presence_xml", "force_active", 1) # do not check XCAP rules
#### XCAP module
loadmodule "xcap.so"
modparam("xcap", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
#### PUA modules
loadmodule "pua.so"
loadmodule "pua_xmpp.so"
modparam("pua","db_url","mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
# the address of the Presence Server where the PUA module should send the
# PUBLISH requests - as we have the PA in the same instance, we send these
# PUBLISH requests to ourselves - be sure and keep this in sync with the
# OpenSIPS socket above !!!
modparam("pua_xmpp", "presence_server", "sip:127.0.0.1:5060 ")
modparam("pua_xmpp", "server_address", "sip:127.0.0.1:5060 ")
#### XMPP parameters
loadmodule "xmpp.so"
# the name that OpenSIPS will register with as a component to the jabber server
modparam("xmpp", "xmpp_domain", "sip.domain.com")
# the location of the jabber server
modparam("xmpp", "xmpp_host", "xmpp.domain.com")
# the domain of the sip users visible to the xmpp users
modparam("xmpp", "sip_domain", "sip.domain.com")
modparam("xmpp", "backend", "component")
modparam("xmpp", "outbound_proxy", "sip:127.0.0.1:5060")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
` if (is_method("SUBSCRIBE") && is_myself("$rd")) {
# in-dialog subscribe requests
route(handle_presence);
exit;
}
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# SIP to XMPP traffic (to an XMPP user)
if ( $rd=="xmpp.domain.com" ) {
# handle initial presence messages
if ( is_method("PUBLISH|SUBSCRIBE") )
route(handle_presence);
# handle xmpp messages
if (is_method("MESSAGE") ) {
t_newtran();
if (xmpp_send_message()) {
t_reply(200, "Accepted");
} else {
t_reply(404, "Not found");
}
exit;
}
} # SIP 2 XMPP
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (is_method("INVITE")) {
# keep dialog state
create_dialog();
# account directly as CDRs
do_accounting("log","cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
# SIP 2 SIP presence traffic
if( is_method("PUBLISH|SUBSCRIBE")) {
route(handle_presence);
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
# Presence route
route[handle_presence]
{
if (!t_newtran()) {
sl_reply_error();
exit;
}
# if it is NOTIFY - for xmpp gateway
if( is_method("NOTIFY")) {
t_reply(200, "OK");
pua_xmpp_notify();
} else
if (is_method("PUBLISH")) {
handle_publish();
} else
if (is_method("SUBSCRIBE")) {
handle_subscribe();
if( $hdr(Event)== "presence" && ($rd=="xmpp.domain.com") )
pua_xmpp_req_winfo("$ru", $hdr(Expires));
}
exit;
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}

OpenSIPS Config - Basic Presence RLS usage

Section titled “OpenSIPS Config - Basic Presence RLS usage”
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://docs.opensips.org/
# for an explanation of available statements, functions and parameters.
#
# Valid for OpenSIPS versions 2.3 and above
# Resource List Server
# RLS + SIP Presence Server
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog","db_mode",0)
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_xml.so"
modparam("presence", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("presence", "fallback2db", 0)
modparam("presence_xml", "force_active", 1) # do not check XCAP rules
#### XCAP module
loadmodule "xcap.so"
modparam("xcap", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("xcap", "integrated_xcap_server", 1)
#### PUA and RLS modules
loadmodule "pua.so"
loadmodule "rls.so"
modparam("pua","db_url","mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
# the address of the Presence Server where the PUA module should send the
# PUBLISH requests - as we have the PA in the same instance, we send these
# PUBLISH requests to ourselves - be sure and keep this in sync with the
# OpenSIPS socket above !!!
modparam("rls", "presence_server", "sip:127.0.0.1:5060 ")
modparam("rls", "to_presence_code", 10)
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
` if (is_method("SUBSCRIBE") && is_myself("$rd")) {
# in-dialog subscribe requests
route(handle_presence);
exit;
}
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (is_method("INVITE")) {
# keep dialog state
create_dialog();
# account directly as CDRs
do_accounting("log","cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
# SIP 2 SIP presence traffic
if( is_method("PUBLISH|SUBSCRIBE")) {
route(handle_presence);
}
if (is_method("NOTIFY")) {
t_newtran();
rls_handle_notify();
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
# Presence route
route[handle_presence]
{
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(is_method("PUBLISH")) {
handle_publish();
} else
if( is_method("SUBSCRIBE")) {
rls_handle_subscribe();
if ( $rc==10 ) {
# SUBSCRIBE not hanled by RLS
handle_subscribe();
}
}
exit;
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}

OpenSIPS Config - How to use Script Helper

Section titled “OpenSIPS Config - How to use Script Helper”
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0) # no DB
#### SCRIPT HELPER module
loadmodule "script_helper.so"
# this route will be run right before sequential requests are routed out
modparam("script_helper", "sequential_route", "my_seq_route")
modparam("script_helper", "use_dialog", 1)
modparam("script_helper", "create_dialog_flags", "bye-on-timeout,options-ping-caller,options-ping-callee")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# account only INVITEs
if (is_method("INVITE")) {
do_accounting("log","cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
route [my_seq_route]
{
xlog("---- Sequential request handler ---- \n");
xlog("$rm | Call-ID: $ci | From-tag: $ft | To-tag: $tt\n");
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This is a basic residential configuration. Ready-to-use M4 templates are
# available under examples/templates/.
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
loadmodule "proto_udp.so"
loadmodule "dialog.so"
loadmodule "b2b_entities.so"
loadmodule "siprec.so"
loadmodule "rtp_relay.so"
loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7899")
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
create_dialog();
$rtp_relay = "co";
$rtp_relay_peer = "co";
rtp_relay_engage("rtpproxy");
siprec_start_recording("sip:127.0.0.1:5090");
do_accounting("log");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}
#
# OpenSIPS SIPREC sample using dispatcher for SRS selection.
#
# The SIPREC module is engaged with a local placeholder SRS URI:
#
# sip:srs@siprec-dispatcher.invalid
#
# The locally generated SIPREC INVITE is then caught in local_route,
# where dispatcher selects the real SRS destination. Dispatcher set 1
# is expected to contain the SIPREC Recording Servers, for example:
#
# setid destination
# 1 sip:127.0.0.1:5090
# 1 sip:127.0.0.1:5091
#
####### Global Parameters #########
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
mpath="/usr/local/lib/opensips/modules/"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
loadmodule "rr.so"
modparam("rr", "append_fromtag", 0)
loadmodule "maxfwd.so"
loadmodule "sipmsgops.so"
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
loadmodule "acc.so"
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
modparam("acc", "detect_direction", 0)
loadmodule "proto_udp.so"
loadmodule "dialog.so"
loadmodule "b2b_entities.so"
loadmodule "siprec.so"
loadmodule "rtp_relay.so"
loadmodule "rtpproxy.so"
loadmodule "dispatcher.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7899")
# Dispatcher must be provisioned with the SRS pool in set 1.
# Uncomment the DB module/db_url below and replace the URL with your DB.
# loadmodule "db_mysql.so"
# modparam("dispatcher", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("dispatcher", "ds_ping_interval", 30)
modparam("dispatcher", "ds_probing_mode", 1)
####### Routing Logic ########
route {
if (!mf_process_maxfwd_header(10)) {
send_reply(483, "Too Many Hops");
exit;
}
if (has_totag()) {
if (is_method("ACK") && t_check_trans()) {
t_relay();
exit;
}
if (!loose_route()) {
send_reply(404, "Not here");
exit;
}
if (is_method("BYE"))
do_accounting("log", "failed");
route(relay);
exit;
}
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
if (!is_method("REGISTER")) {
if (!is_myself("$fd") && !is_myself("$rd")) {
send_reply(403, "Relay Forbidden");
exit;
}
}
if (loose_route()) {
xlog("L_ERR", "Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403, "Preload Route denied");
exit;
}
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (is_method("INVITE")) {
create_dialog();
$rtp_relay = "co";
$rtp_relay_peer = "co";
rtp_relay_engage("rtpproxy");
# Use a stable internal placeholder. local_route below will replace
# its domain with a dispatcher-selected SIPREC Recording Server.
siprec_start_recording("sip:srs@siprec-dispatcher.invalid");
do_accounting("log");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU == NULL) {
send_reply(484, "Address Incomplete");
exit;
}
if (!lookup("location", "method-filtering")) {
t_reply(404, "Not Found");
exit;
}
do_accounting("log", "missed");
route(relay);
}
route[relay] {
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay())
send_reply(500, "Internal Error");
exit;
}
local_route {
# Only touch the SIPREC INVITE generated by siprec_start_recording().
if (!is_method("INVITE") || $ru != "sip:srs@siprec-dispatcher.invalid")
exit;
# set=1 is the SRS dispatcher set; alg=4 hashes over the Call-ID.
# The "f" flag saves remaining destinations for ds_next_domain().
if (!ds_select_domain(1, 4, "f")) {
xlog("L_ERR", "No active SIPREC SRS destination for $ci\n");
drop;
}
xlog("L_INFO", "Selected SIPREC SRS $ru for $ci\n");
t_on_failure("siprec_srs_failure");
}
failure_route[siprec_srs_failure] {
if (t_was_cancelled())
exit;
if (t_check_status("5[0-9][0-9]") ||
(t_check_status("408") && t_local_replied("all"))) {
xlog("L_WARN", "SIPREC SRS $du failed with code $T_reply_code for $ci\n");
# Put the failing SRS into probing state, then try the next server
# saved by ds_select_domain(..., "f").
ds_mark_dst("p");
if (ds_next_domain()) {
xlog("L_INFO", "Trying next SIPREC SRS $ru for $ci\n");
t_on_failure("siprec_srs_failure");
t_relay();
exit;
}
xlog("L_ERR", "No more SIPREC SRS destinations for $ci\n");
}
}
branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}
onreply_route[handle_nat] {
xlog("incoming reply\n");
}
failure_route[missed_call] {
if (t_was_cancelled())
exit;
}
# sample config script to use speeddial module
#
# ----------- global configuration parameters ------------------------
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
# ------------------ module loading ----------------------------------
mpath="/usr/local/lib/opensips/modules"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mysql.so"
loadmodule "speeddial.so"
loadmodule "mi_fifo.so"
# ----------------- setting module-specific parameters ---------------
# -- mi_fifo params --
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
# -- usrloc params --
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
# ------------------------- request routing logic -------------------
# main routing logic
route{
# initial sanity checks
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 (loose_route())
{
if (!t_relay())
{
sl_reply_error();
};
exit;
};
if (!is_myself("$rd"))
{
if (!t_relay())
{
sl_reply_error();
};
exit;
};
if (is_myself("$rd"))
{
if ($rm=="REGISTER")
{
save("location");
exit;
};
if($ru=~"sip:[0-9]{2}@.*")
sd_lookup("speeddial");
lookup("aliases");
if (!is_myself("$rd"))
{
if (!t_relay())
{
sl_reply_error();
};
exit;
};
if (!lookup("location"))
{
sl_send_reply(404, "Not Found");
exit;
};
};
if (!t_relay())
{
sl_reply_error();
};
}

Simple working example, on top of the default SIP-to-SIP configuration, showing how to do parallel forking by adding one more branch (to a mobile number) when routing a call to a user (registration based)

#
# OpenSIPS Parallel Forking configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
# We start from the default SIP 2 SIP calling setup. What we do here with the
# calls to user is to send them to the registered contacts, but also to
# a pre-configured mobile number of the user. So parallel forking to SIP
# and mobile devices.
# For this purpose we consider an extra column in the subscriber table:
# * "did", default null, string(64) - the DID for parallel ringing
# Note that we have no authentication or authorization here,
# this is just an example
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### DB MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0) # no DB
# we need the dialog module mainly for accouting with CDRs,
# not for the call forking
#### SQL OPerationS module
loadmodule "sqlops.so"
modparam("sqlops","db_url","mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
create_dialog();
do_accounting("log", "cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# remember callee's SIP URI, lookup() will change the RURI
$avp(callee) = "sip:"+$rU+"@"+$rd;
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# we have one or multiple registrations of SIP devices
xlog("[$ci] $avp(callee) has SIP branches [$(msg.branch.uri[*])]\n");
# now check for the mobile DID in the subscriber table
sql_query("select did from subscriber where username='$(avp(callee){uri.user})' and domain='$(avp(callee){uri.domain})' ", "$avp(did)");
if ($rc<0 || $avp(did)==NULL) {
xlog("unable to find a did for the user $avp(callee)\n");
} else {
# do parallel forking to it by adding it as new branch
$msg.branch = "sip:"+$avp(did)+"@IP_OF_PSTN_CARRIER";
# set the "pstn" named flag for this branch
$msg.branch.flag(pstn) = 1;
}
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
# this t_rely will take all the branches we collected so
# far (SIP and PSTN) and send them out in the same time
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
xlog("[$ci] t_relay to $avp(callee) with branches [$(msg.branch.uri[*])]\n");
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("[$ci] new branch $T_branch_idx going to $ru/$du, is_pstn = $tm.branch.flag(pstn)\n");
}
onreply_route[handle_nat] {
xlog("incoming $rs/$rr reply received on branch $T_branch_idx\n");
}
failure_route[missed_call] {
xlog("[$ci] final reply $T_reply_code on branch $T_branch_idx, is_pstn = $tm.branch.flag(pstn)\n");
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply(404,"Not found");
## exit;
##}
}

Simple working example, on top of the default SIP-to-SIP configuration, showing how to do serial forking by re-routing the call to a mobile number if the user does not take the call on his SIP devices.

#
# OpenSIPS Parallel Forking configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
# We start from the default SIP 2 SIP calling setup. What we do here with the
# calls to user is to send them to the registered contacts, and if not
# answered , we do serial forking to a pre-configured mobile number of
# the user. So serial forking (on no answer) to mobile devices.
# For this purpose we consider an extra column in the subscriber table:
# * "did", default null, string(64) - the DID for parallel ringing
# Note that we have no authentication or authorization here,
# this is just an example
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### DB MYSQL module
loadmodule "db_mysql.so"
#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "db_mode", 0) # no DB
# we need the dialog module mainly for accouting with CDRs,
# not for the call forking
#### SQL OPerationS module
loadmodule "sqlops.so"
modparam("sqlops","db_url","mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route{
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if ( !(is_method("REGISTER") ) ) {
if (is_myself("$fd")) {
} else {
# if caller is not local, then called number must be local
if (!is_myself("$rd")) {
send_reply(403,"Relay Forbidden");
exit;
}
}
}
# preloaded route checking
if (loose_route()) {
xlog("L_ERR",
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
send_reply(403,"Preload Route denied");
exit;
}
# record routing
if (!is_method("REGISTER|MESSAGE"))
record_route();
# account only INVITEs
if (is_method("INVITE")) {
create_dialog();
do_accounting("log", "cdr");
}
if (!is_myself("$rd")) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# requests for my domain
if (is_method("PUBLISH|SUBSCRIBE")) {
send_reply(503, "Service Unavailable");
exit;
}
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ($rU==NULL) {
# request with no Username in RURI
send_reply(484,"Address Incomplete");
exit;
}
# remember callee's SIP URI, lookup() will change the RURI
$avp(callee) = "sip:"+$rU+"@"+$rd;
# do lookup with method filtering
if (!lookup("location","method-filtering")) {
t_reply(404, "Not Found");
exit;
}
# we have one or multiple registrations of SIP devices
xlog("[$ci] $avp(callee) has SIP branches [$(msg.branch.uri[*])]\n");
# when routing via usrloc, log the missed calls also
do_accounting("log","missed");
route(relay);
}
route[relay] {
# for INVITEs enable some additional helper routes
if (is_method("INVITE")) {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
xlog("[$ci] t_relay to $avp(callee) with branches [$(msg.branch.uri[*])]\n");
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
branch_route[per_branch_ops] {
xlog("[$ci] new branch $T_branch_idx going to $ru/$du, is_pstn = $tm.branch.flag(pstn)\n");
}
onreply_route[handle_nat] {
xlog("incoming $rs/$rr reply received on branch $T_branch_idx\n");
}
failure_route[missed_call] {
xlog("[$ci] final reply $T_reply_code on branch $T_branch_idx, is_pstn = $tm.branch.flag(pstn)\n");
if (t_was_cancelled()) {
exit;
}
# we get here only if all the branches to the SIP registered devices
# failed to establish (none was answered)
# now check for the mobile DID in the subscriber table
sql_query("select did from subscriber where username='$(avp(callee){uri.user})' and domain='$(avp(callee){uri.domain})' ", "$avp(did)");
if ($rc<0 || $avp(did)==NULL) {
xlog("unable to find a did for the user $avp(callee)\n");
# allow whaterver final reply we got to be sent
# back to caller, do not create any new branch
} else {
# do serial forking to it by adding it as a new RURI
$ru = "sip:"+$avp(did)+"@IP_OF_PSTN_CARRIER";
# set the "pstn" named flag for this branch
$msg.branch.flag(pstn) = 1;
# just send out this new branch to PSTN carrier
t_relay();
# after this t_relay(), if failing, there will be no failure route
# as we didn't set one again. The failure route resets itself
# after each triggering
}
}

Next is presented a sample configuration file one can use to implement a standalone SIP-to-XMPP gateway. You can run an instance of OpenSIPS on a separate machine or on different port with the following config, and have the main SIP server configured to forward all SIP requests for XMPP world to it.

#
# simple quick-start config script for XMPP GW
#
# make sure in your main SIP server that you send
# only the adequate SIP MESSAGES to XMPP GW
#
#
# ----------- global configuration parameters ------------------------
log_level=3 # debug level (cmd line: -dddddddddd)
stderror_enabled=no
syslog_enabled=yes
/* Uncomment these line to enter debugging mode */
#debug_mode=yes
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
udp_workers=4
socket=udp:10.10.10.10:5076
alias=sip-xmpp.opensips.org
# ------------------ module loading ----------------------------------
mpath="/usr/local/opensips/lib/opensips/modules/"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"
# XMPP
loadmodule "xmpp.so"
modparam("xmpp", "xmpp_domain", "xmpp-sip.opensips.org")
modparam("xmpp", "xmpp_host", "xmpp.opensips.org")
#modparam("xmpp", "backend", "server")
modparam("xmpp", "backend", "component")
# ----------------- setting module-specific parameters ---------------
# -- mi_fifo params --
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo_xmpp")
# ------------------------- request routing logic -------------------
# main routing logic
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;
};
### absorb retransmissions ###
if (!t_newtran()) {
sl_reply_error();
return;
}
if (is_method("MESSAGE")) {
log("*** xmpp-handled MESSAGE message.\n");
if (xmpp_send_message()) {
t_reply(200, "Accepted");
} else {
t_reply(404, "Not found");
}
return;
}
log("*** xmpp: unhandled message type\n");
t_reply(503, "Service unavailable");
return;
}

In this example, OpenSIPS, based on the received RURI, builds at script level a Contact header which is appended to the 302 Redirect reply.

#
# OpenSIPS Redirect Server configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
# Here we implement a SIP redirect server by manually building the CONTACT
# header to be added in the 302 reply. The SIP URIs to redirect to are
# loaded from DB (based on R-URI of the incoming INVITE) and pushed into
# the CONTACT hdr via string operations
# We assume the mysql table "lcr_table" as
# "destination_did", not null, unique, string(64) - DID to be redirected
# "gw_uri", not null, string(64) - the SIP URI where to redirect
# "gw_prio", not null, string(32) - Q value of the SIP URI
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### DB MYSQL module
loadmodule "db_mysql.so"
#### SQL OPerationS module
loadmodule "sqlops.so"
modparam("sqlops","db_url","mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route {
if ( $(si{ip.matches,192.168.1.1/24})==1 && $rm=="INVITE") {
# the the SQL query to load the set of GW + PRIOrities (Q value)
sql_query("select gw_uri,gw_prio from lcr_table where destination_did='$rU'", "$avp(gw_uri);$avp(gw_prio)");
if ($rc<0) {
t_reply( 404, "Destination not found");
exit;
}
# here we have a set of GW URIs and GW PRIOs (same size) to be added
# to the contact hdr.
$var(i) = 0;
$var(hdr) = "";
while ( $(avp(gw_uri)[$var(i)])!=NULL ) {
# we add each set of GW and PRIO as ", <gw_uri>;q=val"
if ($var(i)!=0)
$var(hdr) = $var(hdr) + ", ";
$var(hdr) = $var(hdr) + "<"+$(avp(gw_uri)[$var(i)])+">;q="+$(avp(gw_prio)[$var(i)]);
# move to the next GW + PRIO set
$var(i) = $var(i) + 1;
}
# add the Contact hdr
append_to_reply("Contact: $var(hdr)\r\n");
# send the reply now
t_reply( 302,"LCR Redirect");
} else {
send_reply( 403, "You are not allowed here!" );
}
exit;
}

OpenSIPS Redirect Server - Redirect to user's registrations

Section titled “OpenSIPS Redirect Server - Redirect to user's registrations”

In this example, for the incoming calls, OpenSIPS does redirect to the user's registrations. The message branches ($msg.branch.uri) are used here to make OpenSIPS to automatically build the Contact header for the 302 Redirect reply

#
# OpenSIPS Redirect Server configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
# Here we implement a SIP redirect server by using $MSG.BRANCH (message
# branches) in order to automatically push the SIP URI into the CONTACT
# header to be added in the 302 reply. The SIP URIs to rediret to are
# the registrations of a user - if we call to a user, we will get back
# a redirect with his registrations
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route {
# accept registrations (maybe you can add here some auth)
if (is_method("REGISTER")) {
# store the registration and generate a SIP reply
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
if ( $(si{ip.matches,192.168.1.1/24})==1 && $rm=="INVITE") {
# do the registrations lookup, to find ALL user's registrations
if ( lookup( "location", "to-branches-only") ) {
# user's registrations are already pushed into message
# branches, with Q values, sockets and everything
xlog("found branches are < $(msg.branch.uri[*]) >\n");
}
# just send the reply now, the message branches will automatically
# be pushed as CONTACT in the reply
t_reply( 302,"LCR Redirect");
} else {
send_reply( 403, "You are not allowed here!" );
}
exit;
}

OpenSIPS Redirect Server - Simple LCR rediret, option 2

Section titled “OpenSIPS Redirect Server - Simple LCR rediret, option 2”

This example re-takes the simple LCR, but instead of building the redirect contact manually, at script level, we use the $msg.branch variable to make OpenSIPS to automatically build the Contact header for the 302 Redirect reply

#
# OpenSIPS Redirect Server configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# Please refer to the OpenSIPS Manuals at:
# https://opensips.org/Documentation/Manuals
# for an explanation of available statements, functions and parameters.
#
# Here we implement a SIP redirect server by using $MSG.BRANCH (message
# branches) in order to automatically push the SIP URI into the CONTACT
# header to be added in the 302 reply. The SIP URIs to redirect to are
# loaded from DB (based on R-URI of the incoming INVITE) and pushed into
# the CONTACT hdr via the $msg.branch variable
# We assume the mysql table "lcr_table" as
# "destination_did", not null, unique, string(64) - DID to be redirected
# "gw_uri", not null, string(64) - the SIP URI where to redirect
# "gw_prio", not null, string(32) - Q value of the SIP URI
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
stderror_enabled=no
syslog_enabled=yes
syslog_facility=LOG_LOCAL0
udp_workers=4
socket=udp:127.0.0.1:5060 # CUSTOMIZE ME
####### Modules Section ########
#set module path
mpath="/usr/local/lib/opensips/modules/"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### DB MYSQL module
loadmodule "db_mysql.so"
#### SQL OPerationS module
loadmodule "sqlops.so"
modparam("sqlops","db_url","mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "proto_udp.so"
####### Routing Logic ########
# main request routing logic
route {
if ( $(si{ip.matches,192.168.1.1/24})==1 && $rm=="INVITE") {
# the the SQL query to load the set of GW + PRIOrities (Q value)
sql_query("select gw_uri,gw_prio from lcr_table where destination_did='$rU'", "$avp(gw_uri);$avp(gw_prio)");
if ($rc<0) {
t_reply( 404, "Destination not found");
exit;
}
# here we have a set of GW URIs and GW PRIOs (same size) to be added
# to the contact hdr.
while ( $avp(gw_uri)!=NULL ) {
# add the SIP URI as new branch
$msg.branch = $avp(gw_uri);
# and the Q value to the branch
$msg.branch.q = $avp(gw_prio);
# delete the last used values
$avp(gw_uri) = NULL;
$avp(gw_prio) = NULL;
}
# send the reply now
t_reply( 302,"LCR Redirect");
} else {
send_reply( 403, "You are not allowed here!" );
}
exit;
}