485 lines
14 KiB
INI
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();
|
|
}
|