495 lines
14 KiB
INI
495 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=3
|
|
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")
|
|
|
|
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")
|
|
|
|
|
|
##### N5 HTTP2 Modules and setting
|
|
|
|
loadmodule "rest_client.so"
|
|
modparam("rest_client", "curl_timeout", 7)
|
|
modparam("rest_client", "connection_timeout", 4)
|
|
modparam("rest_client", "curl_http_version", 5)
|
|
|
|
####### 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;
|
|
$avp(sub_id) = "imsi-" + $fU;
|
|
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,;});
|
|
$avp(sub_id) = "imsi-" + $tU;
|
|
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(afAppId) = "+g.3gpp.icsi-ref=\\\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\\\"";
|
|
$var(dnn) = "ims";
|
|
$json(array1) := "[\"permit in ip from "+$var(src_ip)+" "+$var(src_port)+" to "+$var(dst_ip)+" "+$var(dst_port)+"\", \"permit out ip from "+$var(dst_ip)+" "+$var(dst_port)+" to "+$var(src_ip)+" "+$var(src_port)+"\"]";
|
|
$var(events) = "[{\"event\": \"QOS_NOTIF\", \"notifMethod\": \"PERIODIC\"}, {\"event\": \"ANI_REPORT\", \"notifMethod\": \"ONE_TIME\"}]";
|
|
$var(notifUri) = "http://N5_BIND_IP:N5_BIND_PORT";
|
|
$var(sponStatus) = "SPONSOR_DISABLED";
|
|
$var(supi) = "imsi-"+ $au;
|
|
$var(suppFeat) = "2";
|
|
$var(ueIpv4) = $var(src_ip);
|
|
|
|
$json(nf_reg_body) = "{
|
|
\"ascReqData\":{
|
|
\"afAppId\": \""+$var(afAppId)+"\",
|
|
\"dnn\": \""+$var(dnn)+"\" ,
|
|
\"medComponents\":{
|
|
\"0\":{
|
|
\"medCompN\":0,
|
|
\"qosReference\":\"qosVoNR\",
|
|
\"medType\":\"CONTROL\",
|
|
\"medSubComps\":{
|
|
\"0\":{
|
|
\"fNum\":0,
|
|
\"fDescs\": "+$json(array1)+",
|
|
\"fStatus\":\"ENABLED\",
|
|
\"flowUsage\":\"AF_SIGNALLING\"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
\"evSubsc\":{ \"events\": "+$var(events)+"},
|
|
\"notifUri\": \""+$var(notifUri)+"\" ,
|
|
\"sponStatus\": \""+$var(sponStatus)+"\",
|
|
\"supi\": \""+$var(supi)+"\",
|
|
\"suppFeat\": \""+$var(suppFeat)+"\",
|
|
\"ueIpv4\": \""+$var(ueIpv4)+"\"
|
|
}
|
|
}";
|
|
rest_post("http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$json_pretty(nf_reg_body)", "application/json" , $var(resp), $var(ct), $var(rcode));
|
|
xlog("L_INFO", "N5 Response: [$(hdr(location)) ] \n");
|
|
xlog("L_INFO", "N5 Response: [$var(resp)] \n");
|
|
xlog("L_INFO", "N5 Response: [$var(ct)] \n");
|
|
xlog("L_INFO", "N5 Response: [$var(rcode)] \n");
|
|
break;
|
|
|
|
case "audio":
|
|
$var(afAppId) = "+g.3gpp.icsi-ref=\\\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\\\"";
|
|
$var(dnn) = "ims";
|
|
|
|
$json(array1) := "[\"permit in ip from "+$avp(ip)+" "+$avp(port)+" to "+$var(ip)+" "+$var(port)+"\", \"permit out ip from "+$var(ip)+" "+$var(port)+" to "+$avp(ip)+" "+$avp(port)+"\"]";
|
|
$json(array2) := "[\"permit in ip from "+$avp(ip)+" "+$avp(rtcp)+" to "+$var(ip)+" "+$var(rtcp)+"\", \"permit out ip from "+$var(ip)+" "+$var(rtcp)+" to "+$avp(ip)+" "+$avp(rtcp)+"\"]";
|
|
|
|
$var(events) = "[{\"event\": \"QOS_NOTIF\", \"notifMethod\": \"PERIODIC\"}, {\"event\": \"ANI_REPORT\", \"notifMethod\": \"ONE_TIME\"}]";
|
|
$var(notifUri) = "http://N5_BIND_IP:N5_BIND_PORT";
|
|
$var(sponStatus) = "SPONSOR_DISABLED";
|
|
$var(supi) = $avp(sub_id);
|
|
$var(suppFeat) = "2";
|
|
$var(ueIpv4) = $avp(ip);
|
|
|
|
$json(nf_call_body) = "{
|
|
\"ascReqData\": {
|
|
\"afAppId\": \""+$var(afAppId)+"\",
|
|
\"dnn\": \""+$var(dnn)+"\" ,
|
|
\"medComponents\":{
|
|
\"0\":{
|
|
\"medCompN\":0,
|
|
\"qosReference\":\"qosVoNR\",
|
|
\"medType\":\"AUDIO\",
|
|
\"medSubComps\":{
|
|
\"0\":{
|
|
\"fNum\":1,
|
|
\"fDescs\": "+$json(array1)+",
|
|
\"fStatus\":\"ENABLED\",
|
|
\"marBwDl\":\"5000 Kbps\",
|
|
\"marBwUl\":\"3000 Kbps\",
|
|
\"flowUsage\":\"NO_INFO\"
|
|
},
|
|
\"1\":{
|
|
\"fNum\":2,
|
|
\"fDescs\": "+$json(array2)+",
|
|
\"fStatus\":\"ENABLED\",
|
|
\"marBwDl\":\"5000 Kbps\",
|
|
\"marBwUl\":\"3000 Kbps\",
|
|
\"flowUsage\":\"RTCP\"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
\"evSubsc\":{ \"events\": "+$var(events)+"},
|
|
\"notifUri\": \""+$var(notifUri)+"\" ,
|
|
\"sponStatus\": \""+$var(sponStatus)+"\",
|
|
\"supi\": \""+$var(supi)+"\",
|
|
\"suppFeat\": \""+$var(suppFeat)+"\",
|
|
\"ueIpv4\": \""+$var(ueIpv4)+"\"
|
|
}
|
|
}";
|
|
rest_post("http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$json_pretty(nf_call_body)", "application/json" , $var(resp), $var(ct), $var(rcode));
|
|
xlog("L_INFO", "N5 Response: [$(hdr(location)) ] \n");
|
|
xlog("L_INFO", "N5 Response: [$var(resp)] \n");
|
|
xlog("L_INFO", "N5 Response: [$var(ct)] \n");
|
|
xlog("L_INFO", "N5 Response: [$var(rcode)] \n");
|
|
break;
|
|
}
|
|
}
|
|
route[session_termination] {
|
|
if ($si != "SCSCF_IP")
|
|
rtpengine_delete();
|
|
xlog("L_INFO","[$ci] Received BYE from $si for $tu - can't terminate N5: WIP N5 Termination logic\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;
|
|
}
|
|
|
|
|
|
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();
|
|
}
|