Files
2025-08-21 01:09:37 +00:00

485 lines
14 KiB
INI

#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This script was generated via "make menuconfig", from
# the "Residential" scenario.
# You can enable / disable more features / functionalities by
# re-generating the scenario with different options.#
#
# Please refer to the Core CookBook at:
# https://opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=6
xlog_level=3
#mem_log=6
log_stderror=yes
log_stdout=yes
log_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
dns=no
socket=udp:PCSCF_IP:5060
socket=tcp:PCSCF_IP:5060
socket=ipsec:PCSCF_IP:6100,5100
alias="pcscf.IMS_DOMAIN"
#set module path
mpath="/usr/local/opensips/modules"
####### Modules Section ########
#### MYSQL module
loadmodule "db_mysql.so"
#### 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"
#### NATHELPER module
loadmodule "nathelper.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/var/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "mi_dump_kv_store", 1)
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)
#### proto_udp module
loadmodule "dispatcher.so"
loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"
loadmodule "proto_ipsec.so"
loadmodule "dialog.so"
#### dbtext module
loadmodule "db_text.so"
modparam("dispatcher", "db_url", "text:///etc/opensips/db")
#### aaa_diameter module
loadmodule "aaa_diameter.so"
modparam("aaa_diameter", "fd_log_level", 0) # max amount of logging, quite annoying
modparam("aaa_diameter", "realm", "IMS_DOMAIN")
modparam("aaa_diameter", "peer_identity", "hss")
modparam("aaa_diameter", "aaa_url",
"diameter:/etc/opensips/freeDiameter.conf;extra-avps-file:/etc/opensips/pcscf.dictionary")
modparam("proto_ipsec", "min_spi", 10000)
modparam("proto_ipsec", "max_spi", 10100)
modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null, hmac-md5-96=null")
#### RTPENGINE module
loadmodule "rtpengine.so"
modparam("rtpengine", "rtpengine_sock", "udp:RTPENGINE_IP:2223")
loadmodule "event_route.so"
loadmodule "json.so"
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_reginfo.so"
loadmodule "pua.so"
modparam("pua|presence","db_url", "mysql://opensips_pcscf:heslo@MYSQL_IP/opensips_pcscf")
loadmodule "pua_reginfo.so"
modparam("pua_reginfo", "ul_domain", "location")
modparam("pua_reginfo", "ul_identities_key", "identities")
modparam("pua_reginfo", "default_domain", "IMS_DOMAIN")
modparam("pua_reginfo", "server_address", "sip:reginfo@pcscf.IMS_DOMAIN")
####### Routing Logic ########
# main request routing logic
route{
xlog("L_INFO", "[$ci] Start route time [$Tf] method ($rm) r-uri ($ru) \n");
set_via_handling("force-rport");
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(session_termination);
}
if (is_method("UPDATE")) {
if ($si != "SCSCF_IP")
rtpengine_offer("replace-origin");
else
t_on_reply("rtpengine_answer");
}
if (is_method("SUBSCRIBE|NOTIFY") && is_myself($rd)) {
route(handle_presence);
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")) {
xlog("L_INFO", "[$ci] Received REGISTER for $tu - relaying to I-CSCF\n");
append_hf("Path: <sip:term@pcscf.IMS_DOMAIN;lr>\r\n");
if ($hdr(Security-Client)) {
setflag("SEC_AGREE");
append_hf("P-Visited-Network-ID: IMS_DOMAIN\r\n");
}
t_on_reply("register_reply");
route(relay);
exit;
} else if (is_method("SUBSCRIBE|PUBLISH")) {
xlog("L_INFO", "[$ci] Received $rm for $tu - handling\n");
route(handle_presence);
exit;
} else if (is_method("INVITE")) {
if (loose_route()) {
xlog("L_INFO", "[$ci] Received INVITE for $tu - relaying to S-CSCF ($ru/$du)\n");
remove_hf("Security-Verify");
if (list_hdr_has_option("Require", "sec-agree"))
list_hdr_remove_option("Require", "sec-agree");
if (list_hdr_has_option("Proxy-Require", "sec-agree"))
list_hdr_remove_option("Proxy-Require", "sec-agree");
append_hf("P-Visited-Network-ID: IMS_DOMAIN\r\n");
$socket_out = "tcp:PCSCF_IP:5060";
$avp(si) = $si;
rtpengine_offer("replace-origin");
} else {
xlog("L_INFO", "[$ci] Received INVITE for $tu - looking up from S-CSCF ($ru/$du/$tu)\n");
$rU = $(tU{s.select,0,;});
if (!lookup("location")) {
xlog("L_ERR", "[$ci] user $rU not found\n");
t_reply(404, "Not here");
exit;
}
}
route(extract_ip_port);
$avp(ip) = $var(ip);
$avp(port) = $var(port);
$avp(rtcp) = $var(rtcp);
$avp(stream) = $(rb{sdp.stream,0});
t_on_reply("invite_reply");
if (!record_route()) {
xlog("L_ERR", "[$ci] Cannot do record_route()\n");
t_reply(503, "Internal Error");
exit;
}
if (!create_dialog()) {
xlog("L_ERR", "[$ci] Cannot create_dialog()\n");
t_reply(503, "Internal Error");
exit;
}
if (!t_relay()) {
xlog("L_ERR", "[$ci] Cannot relay to $ru/$du\n");
t_reply(503, "Internal Error");
exit;
}
exit;
}
send_reply(405,"Method Not Allowed");
exit;
}
route[relay] {
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
onreply_route[register_reply] {
xlog("L_INFO","[$ci] Received REGISTER reply $rs from $si for $tu\n");
if ($T_reply_code == 401) {
if (!isflagset("SEC_AGREE") || ipsec_create())
route(dm_send_aar, "control");
} else if ($T_reply_code == 200) {
for ($var(item) in $(hdr(P-Associated-URI)[*])) {
$var(uri_len) = $(var(item){s.len}) - 2;
$var(uri) = $(var(item){s.substr, 1, $var(uri_len)});
if (!save("location", "no-reply, path-off", $var(uri))) {
xlog("L_ERR", "[$ci] could not save aor [$var(uri)]\n");
} else {
ul_add_key("location", "$tU@$td", "identities", "$var(uri)");
}
}
reginfo_update("$tU@$td");
}
}
onreply_route[invite_reply] {
if (!has_body_part("application/sdp")) {
xlog("L_INFO","[$ci] Received INVITE reply $rs from $si for $tu - without SDP\n");
return;
} else if (isflagset("INVITE_AAA")) {
xlog("L_INFO","[$ci] Received INVITE reply $rs from $si for $tu - AAA done\n");
return;
}
xlog("L_INFO","[$ci] Received INVITE reply $rs from $si for $tu - doing AAR\n");
route(extract_ip_port);
if ($avp(si) == NULL) {
rtpengine_answer("replace-origin");
$avp(si) = $si;
$var(tmp_ip) = $avp(ip);
$var(tmp_port) = $avp(port);
$avp(ip) := $var(ip);
$avp(port) := $var(port);
$var(ip) = $var(tmp_ip);
$var(port) = $var(tmp_port);
}
route(dm_send_aar, "audio");
setflag("INVITE_AAA");
}
onreply_route[rtpengine_answer] {
if (!has_body_part("application/sdp"))
return;
rtpengine_answer("replace-origin");
}
route[dm_send_aar] {
switch ($param(1)) {
case "control":
if ($ipsec(ip) != NULL) {
$var(src_ip) = $ipsec_ue(ip);
$var(src_port) = $ipsec_ue(port-c);
$var(dst_ip) = $ipsec(ip);
$var(dst_port) = $ipsec(port-s);
$var(sess_port) = $ipsec_ue(port-s);
} else {
$var(src_ip) = $si;
$var(src_port) = $sp;
$var(dst_ip) = $socket_in(ip);
$var(dst_port) = $socket_in(port);
$var(sess_port) = $sp;
}
$var(media_component) = "[{\"Media-Component-Number\": 1},
{\"Media-Sub-Component\": [{\"Flow-Number\": 1},
{\"Flow-Description\": \"permit in ip from "+$var(src_ip)+" "+$var(src_port)+" to "+$var(dst_ip)+" "+$var(dst_port)+"\"},
{\"Flow-Description\": \"permit out ip from "+$var(dst_ip)+" "+$var(dst_port)+" to "+$var(src_ip)+" "+$var(src_port)+"\"},
{\"Flow-Usage\": 2}]},
{\"Media-Type\": 4},
{\"Codec-Data\": \"uplink\noffer\n\"},
{\"Codec-Data\": \"downlink\nanswer\n\"},
{\"Flow-Status\": 2}]";
$avp(si) = $var(src_ip);
$var(session_id) = $var(src_ip) + ";" + $var(sess_port) + ";pcscf.IMS_DOMAIN;"+$Ts+"."+$Tsm+";"+$pp;
break;
case "audio":
$var(session_id) = "pcscf.IMS_DOMAIN;"+$Ts+"."+$Tsm+";"+$pp;
$var(media_component) = "[{\"Media-Component-Number\": 1},
{\"Media-Sub-Component\": [{\"Flow-Number\": 1},
{\"Flow-Description\": \"permit in 17 from "+$avp(ip)+" "+$avp(port)+" to "+$var(ip)+" "+$var(port)+"\"},
{\"Flow-Description\": \"permit out 17 from "+$var(ip)+" "+$var(port)+" to "+$avp(ip)+" "+$avp(port)+"\"},
{\"Flow-Description\": \"permit in 17 from "+$avp(ip)+" "+$avp(rtcp)+" to "+$var(ip)+" "+$var(rtcp)+"\"},
{\"Flow-Description\": \"permit out 17 from "+$var(ip)+" "+$var(rtcp)+" to "+$avp(ip)+" "+$avp(rtcp)+"\"},
{\"Flow-Usage\": 0}]},
{\"Media-Type\": 0},
{\"Max-Requested-Bandwidth-DL\": 41000},
{\"Max-Requested-Bandwidth-UL\": 41000},
{\"Codec-Data\": \"uplink\noffer\n"+$avp(stream)+"\"},
{\"Codec-Data\": \"downlink\nanswer\n"+$(rb{sdp.stream,0})+"\"},
{\"Flow-Status\": 2}]";
$dlg_val(session_id) = $var(session_id);
break;
}
$var(payload) = "[
{ \"Session-Id\": \""+$var(session_id)+"\" },
{ \"Auth-Application-Id\": 16777236 },
{ \"Origin-Host\": \"pcscf.IMS_DOMAIN\" },
{ \"Origin-Realm\": \"IMS_DOMAIN\" },
{ \"Destination-Realm\": \"EPC_DOMAIN\" },
{ \"Vendor-Specific-Application-Id\": [{\"Vendor-Id\": 10415},
{\"Auth-Application-Id\": 16777236}]},
{ \"AF-Application-Identifier\": \"IMS Services\" },
{ \"Authorization-Lifetime\": 3600 },
{ \"Subscription-ID\": [{\"Subscription-Id-Type\": 2},
{\"Subscription-Id-Data\": \""+$fu+"\"}]},
{ \"Reservation-Priority\": 0 },
{ \"Media-Component-Description\": "+$var(media_component)+"},
{ \"Frame-IP-Address\": \""+$avp(si)+"\" },
{ \"Specific-Action\": 1 },
{ \"Specific-Action\": 2 },
{ \"Specific-Action\": 3 },
{ \"Specific-Action\": 4 },
{ \"Specific-Action\": 5 },
{ \"Specific-Action\": 6 },
{ \"Specific-Action\": 12 },
{ \"Auth-Grace-Period\": 0 },
{ \"Session-Timeout\": 3600 }
]";
$var(rc) = dm_send_request(16777236, 265, $var(payload), $var(rpl_avps));
xlog("[$ci] AAA rc: $var(rc), AAA AVPs: $var(rpl_avps)\n");
}
route[session_termination] {
if ($si != "SCSCF_IP")
rtpengine_delete();
xlog("L_INFO","[$ci] Received BYE from $si for $tu - doing STR\n");
$var(payload) = "[
{ \"Session-Id\": \""+$dlg_val(session_id)+"\" },
{ \"Auth-Application-Id\": 16777236 },
{ \"Origin-Host\": \"pcscf.IMS_DOMAIN\" },
{ \"Origin-Realm\": \"IMS_DOMAIN\" },
{ \"Destination-Realm\": \"EPC_DOMAIN\" },
{ \"Vendor-Specific-Application-Id\": [{\"Vendor-Id\": 10415},
{\"Auth-Application-Id\": 16777236}]},
{ \"AF-Application-Identifier\": \"IMS Services\" },
{ \"Termination-Cause\": 1 }
]";
$var(rc) = dm_send_request(16777236, 275, $var(payload), $var(rpl_avps));
xlog("[$ci] STA rc: $var(rc), STA AVPs: $var(rpl_avps)\n");
}
route[extract_ip_port] {
$var(ip) = $(rb{sdp.line,c}{s.select,2, });
$var(port) = $(rb{sdp.line,m}{s.select,1, });
$var(rtcp) = $(var(port){s.int}) + 1;
}
event_route[E_DM_REQUEST] {
if ($param(app_id) == 16777236 && $param(cmd_code) == 274) {
$var(ip) = $(param(sess_id){s.select,0,;});
$var(port) = $(param(sess_id){s.select,1,;}{s.int});
xlog("[diameter] removing $var(ip):$var(port) contact\n");
remove_ip_port($var(ip), $var(port), "location");
$var(payload) = "[
{ \"Vendor-Specific-Application-Id\": [{\"Vendor-Id\": 10415},
{\"Auth-Application-Id\": 16777236}]},
{ \"Result-Code\": 2001 },
{ \"Auth-Session-State\": 0 },
{ \"Origin-Host\": \"pcscf.IMS_DOMAIN\" },
{ \"Origin-Realm\": \"IMS_DOMAIN\" }
]";
dm_send_answer($var(payload));
}
}
route[handle_presence] {
if (!t_newtran()){
sl_reply_error();
exit;
}
if ($hdr(Event) != "reg") {
xlog("L_ERR", "[$ci] Unhandled event $hdr(Event)\n");
send_reply(489, "Bad Event");
exit;
}
if (is_method("PUBLISH"))
handle_publish();
if (is_method("SUBSCRIBE"))
handle_subscribe();
}