roles: add ims role from c3gsm

This commit is contained in:
Alexander Couzens 2024-02-06 10:31:17 +01:00
commit e2947e2955
46 changed files with 6175 additions and 0 deletions

8
hosts Normal file
View File

@ -0,0 +1,8 @@
[epdg]
epdg.osmocom.org
[epc]
epc.epdg.osmocom.org
[ims]
ims.epdg.osmocom.org

2
roles/ims/README.md Normal file
View File

@ -0,0 +1,2 @@
# under MIT
# Alexander Couzens <lynxis@fe80.eu>

View File

@ -0,0 +1,32 @@
---
ims_mcc: "901"
ims_mnc: "070"
# create pcscf
## wether db should be initialized (any idea if we can check this?)
ims_pcscf_db_init: false
ims_pcscf_db: pcscf
ims_pcscf_user: pcscf
ims_pcscf_pass: pcscf
ims_pcscf_sip_bind: "udp:0.0.0.0:5060"
ims_pcscf_diameter_bind_ip: 192.168.150.155
ims_pcscf_diameter_bind_port: 3868
# create icscf
ims_icscf_db_init: false
ims_icscf_db: icscf
ims_icscf_user: icscf
ims_icscf_pass: icscf
ims_icscf_sip_bind: "udp:0.0.0.0:4060"
ims_icscf_diameter_bind_ip: 192.168.150.155
ims_icscf_diameter_bind_port: 3867
# create scscf
ims_scscf_db_init: false
ims_scscf_db: scscf
ims_scscf_user: scscf
ims_scscf_pass: scscf
ims_scscf_sip_bind: "udp:0.0.0.0:3060"
ims_scscf_diameter_bind_ip: 192.168.150.155
ims_scscf_diameter_bind_port: 3866

View File

@ -0,0 +1,630 @@
#!KAMAILIO
#
# This config file implements the basic I-CSCF functionality
# - web: http://www.kamailio.org
# - git: http://sip-router.org
#
# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php
# for an explanation of possible statements, functions and parameters.
#
# Direct your questions about this file to: <sr-users@lists.kamailio.org>.
#
# For more information about the various parameters, functions and statements
# try http://sip-router.org/wiki/ .
#
system.shutdownmode = 0 desc "System shutdown mode"
system.service = "Interrogating-CSCF" desc "Function of this server"
include_file "icscf.cfg"
####### Defined Values #########
# *** Value defines - IDs used later in config
# - flags
# FLT_ - per transaction (message) flags
# FLB_ - per branch flags
#!define FLT_CAPTURE 1
#!ifdef WITH_XMLRPC
listen=tcp:127.0.0.1:4060
#!endif
####### Global Parameters #########
#!ifdef WITH_DEBUG
debug=5
log_stderror=yes
sip_warning=yes
#!else
debug=2
log_stderror=no
sip_warning=no
#!endif
user_agent_header="User-Agent: Kamailio I-CSCF"
server_header="Server: Kamailio I-CSCF"
/* comment the next line to enable the auto discovery of local aliases
based on reverse DNS on IPs (default on) */
auto_aliases=no
# Do SRV-Loadbalancing:
dns_srv_lb=yes
# Always: Also try IPv6:
dns_try_ipv6=yes
# Query NAPTR-Records as well:
dns_try_naptr=no
#!ifdef WITH_XMLRPC
#!ifndef WITH_TCP
#!define WITH_TCP
#!endif
#!ifndef TCP_PROCESSES
# Number of TCP Processes
#!define TCP_PROCESSES 3
#!endif
#!endif
#!ifdef WITH_TCP
# life time of TCP connection when there is no traffic
# - a bit higher than registration expires to cope with UA behind NAT
tcp_connection_lifetime=3615
#!ifdef TCP_PROCESSES
tcp_children=TCP_PROCESSES
#!endif
#!else
disable_tcp=yes
#!endif
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
children=64
# ------------------ module loading ----------------------------------
# mpath="/usr/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/:/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/"
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
# (we try both the lib64 and the lib directory)
loadmodule "tm"
loadmodule "sl"
loadmodule "rr"
loadmodule "pv"
loadmodule "textops"
loadmodule "maxfwd"
loadmodule "sanity"
loadmodule "siputils"
loadmodule "kex"
loadmodule "tmx"
loadmodule "pike"
loadmodule "corex"
# Control interfaces:
loadmodule "ctl"
loadmodule "cfg_rpc"
#!ifdef WITH_XMLRPC
loadmodule "xmlrpc"
#!endif
# Load the according DB-Module:
loadmodule "db_mysql"
#!ifdef DB_URL2
loadmodule "db_cluster"
#!endif
loadmodule "cdp.so"
loadmodule "cdp_avp.so"
loadmodule "xlog.so"
loadmodule "ims_icscf.so"
#!ifdef CAPTURE_NODE
loadmodule "siptrace.so"
#!endif
#!ifdef WITH_DEBUG
loadmodule "debugger.so"
#!endif
#!ifdef WITH_TLS
loadmodule "tls.so"
#!endif
#!ifdef PEERING
loadmodule "enum"
#!endif
# ----------------- setting module-specific parameters ---------------
#!ifdef DB_URL2
# ----- db_cluster params -----
modparam("db_cluster", "connection", DB_URL)
modparam("db_cluster", "connection", DB_URL2)
modparam("db_cluster", "cluster", "cluster1=>con1=2s2s;con2=1s1s")
#!endif
loadmodule "jsonrpcs.so"
# ----- jsonrpcs params -----
modparam("jsonrpcs", "pretty_format", 1)
/* set the path to RPC fifo control file */
modparam("jsonrpcs", "fifo_name", "/run/kamailio_icscf/kamailio_rpc.fifo")
/* set the path to RPC unix socket control file */
modparam("jsonrpcs", "dgram_socket", "/run/kamailio_icscf/kamailio_rpc.sock")
# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
# -- cdp params --
modparam("cdp","config_file","/etc/kamailio_icscf/icscf.xml")
# ----- icscf params -----
# Comment the following line to enable realm routing
#!ifdef CXDX_FORCED_PEER
modparam("ims_icscf", "cxdx_forced_peer", CXDX_FORCED_PEER)
#!endif
modparam("ims_icscf","cxdx_dest_realm", NETWORKNAME)
# DB-URL, where information about S-CSCF-Server can be found:
#!ifdef DB_URL2
modparam("ims_icscf", "db_url", "cluster://cluster1")
#!else
modparam("ims_icscf", "db_url", DB_URL)
#!endif
#!ifdef PEERING
# Route which is executed, in case HSS returned "User-Unknown" on LIR request
modparam("ims_icscf","route_lir_user_unknown", "lir_term_user_unknown")
#!endif
#!ifdef FALLBACK_AUTH
# Route which is executed, in case HSS returned "User-Unknown" on UAR request
modparam("ims_icscf","route_uar_user_unknown", "uar_term_user_unknown")
#!endif
#!ifdef WITH_TLS
# ----- tls params -----
modparam("tls", "config", "/etc/kamailio_icscf/tls.cfg")
#!endif
#!ifdef WITH_XMLRPC
# ----- xmlrpc params -----
modparam("xmlrpc", "route", "XMLRPC");
modparam("xmlrpc", "url_match", "^/RPC")
#!endif
# ----- ctl params -----
modparam("ctl", "binrpc", "unix:/run/kamailio_icscf/kamailio_ctl")
#!ifdef WITH_DEBUG
# ----- debugger params -----
modparam("debugger", "cfgtrace", 1)
#!endif
#!ifdef CAPTURE_NODE
# Destination, where to send the traffic
modparam("siptrace", "duplicate_uri", CAPTURE_NODE)
# Trace all traffic
modparam("siptrace", "trace_on", 1)
modparam("siptrace", "trace_to_database", 0)
modparam("siptrace", "trace_flag", FLT_CAPTURE)
modparam("siptrace", "hep_mode_on", 1)
#!endif
#!ifdef PEERING
# ----- enum params -----
modparam("enum", "domain_suffix", ENUM_SUFFIX)
#!endif
# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 10sec
modparam("tm", "fr_timer", 10000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)
#!ifdef WITH_DEBUG
loadmodule "debugger.so"
modparam("debugger", "mod_hash_size", 5)
modparam("debugger", "mod_level_mode", 1)
modparam("debugger", "mod_level", "cdp=3")
modparam("debugger", "mod_level", "ims_icscf=3")
#!endif
# ------------------------- request routing logic -------------------
# main routing logic
route{
#!ifdef WITH_DEBUG
xlog("I-CSCF >>>>>>>>>>>>>>>>>>>> $rm $ru ($fu => $tu ($si:$sp) to $tu, $ci)\n");
#!endif
if !($rU =~ "\+.*") {
prefix("+");
}
# per request initial checks
route(REQINIT);
if (is_method("REGISTER")) {
route(register);
}
if (is_method("INVITE|SUBSCRIBE|MESSAGE|INFO|PUBLISH|CANCEL")) {
route(initial_request);
} else {
# Shouldn't get here unless missconfigured (add more methods as initial) or
# somebody is routing unknown messages
append_to_reply("Allow: INVITE,SUBSCRIBE,MESSAGE,INFO,PUBLISH,CANCEL\r\n");
send_reply("406","Initial Request Method not allowed at the I-CSCF");
break;
}
}
######################################################################
# Helper routes (Basic-Checks, NAT-Handling/RTP-Control, XML-RPC)
######################################################################
# Per SIP request initial checks
route[REQINIT] {
$var(used) = 1 - ($stat(free_size) / $stat(total_size));
xlog("L_DBG", "Mem: Total $stat(total_size), Free $stat(free_size) [$var(used)% used]\n");
if ($var(used) > 95) {
send_reply("503", "Server overloaded");
exit;
}
# Trace this message
#!ifdef CAPTURE_NODE
sip_trace();
setflag(FLT_CAPTURE);
#!endif
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7")) {
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
# Check for shutdown mode:
if (!has_totag() && ($sel(cfg_get.system.shutdownmode) > 0)) {
send_reply("503", "Server shutting down");
exit;
}
# Reply to OPTIONS:
if (is_method("OPTIONS") && (uri==myself)) {
options_reply();
exit;
}
# Ignore Re-Transmits:
if (t_lookup_request()) {
exit;
}
if (is_method("INVITE|REGISTER")) {
send_reply("100", "Trying");
}
}
######################################################################
# XMLRPC routing
######################################################################
#!ifdef WITH_XMLRPC
route[XMLRPC] {
if ((method=="POST" || method=="GET")
#!ifdef XMLRPC_WHITELIST_1
&& ((src_ip == XMLRPC_WHITELIST_1)
#!ifdef XMLRPC_WHITELIST_2
|| (src_ip == XMLRPC_WHITELIST_2)
#!endif
#!ifdef XMLRPC_WHITELIST_3
|| (src_ip == XMLRPC_WHITELIST_3)
#!endif
)
#!endif
) {
# close connection only for xmlrpclib user agents (there is a bug in
# xmlrpclib: it waits for EOF before interpreting the response).
if ($hdr(User-Agent) =~ "xmlrpclib")
set_reply_close();
set_reply_no_connect();
dispatch_rpc();
exit;
}
send_reply("403", "Forbidden");
exit;
}
#!endif
######################################################################
# Handling of REGISTER requests
######################################################################
route[register]
{
t_set_fr(5000, 5000);
#first check if we have an S-CSCF list
if (I_scscf_select("0")) {
#there is an S-CSCF list - no need to do a UAR
t_on_reply("register_reply");
t_on_failure("register_failure");
if (!t_relay()) {
send_reply("500","Error forwarding towards S-CSCF");
}
} else {
#no S-CSCF list therefore must do UAR
#free this from the failed I_scscf_select call
I_scscf_drop();
# Do an asynchronous UAR:
#0=REG/DEREG; 1=REG+Capabilities
if (!I_perform_user_authorization_request("REG_UAR_REPLY","0")) {
send_reply("500", "Error in Request");
}
}
exit;
}
route[REG_UAR_REPLY]
{
#xlog("$$avp(s:uaa_return_code) = $avp(s:uaa_return_code)\n");
#this is async so to know status we have to check the reply avp
switch ($avp(s:uaa_return_code)){
case 1: #success
if (I_scscf_select("0")){
t_on_failure("register_failure");
t_on_reply("register_reply");
#now relay to appropriate SCSCF
if (!t_relay()) {
t_reply("500", "Error forwarding to SCSCF");
}
} else {#select failed
I_scscf_drop();
t_reply("500", "Server error on SCSCF Select (UAR)");
}
break;
case -1: #failure
xlog("L_ERR", "UAR failure - error response sent from module\n");
break;
case -2: #error
xlog("L_ERR", "UAR error - sending error response now\n");
t_reply("500", "UAR failed");
break;
default:
xlog("L_ERR", "Unknown return code from UAR, value is [$avp(s:uaa_return_code)]\n");
t_reply("500", "Unknown response code from UAR");
break;
}
}
######################################################################
# Replies to REGISTER requests,
######################################################################
onreply_route[register_reply]
{
xlog("L_DBG", "Enter register reply block");
if (!t_check_status("(408)|(480)")){
if (!t_check_status("(401)")){
xlog("L_DBG", "dropping scscf list on register failure");
I_scscf_drop();
} else {
xlog("L_DBG", "This is a 401 - keep scscf list to do optimisation");
}
}
break;
}
######################################################################
# Failed REGISTERs
######################################################################
failure_route[register_failure]
{
if (t_branch_timeout() || t_check_status("([5-6][0-9][0-9])")){
if (I_scscf_select("1")) {
t_on_reply("register_reply");
t_on_failure("register_failure");
if (!t_relay()) {
t_reply("500","Error forwarding towards next S-CSCF");
break;
}
break;
} else {
t_reply("500", "Server error on UAR select next S-CSCF");
break;
}
} else {
if (!t_check_status("(401)")){
xlog("L_DBG", "dropping scscf list on register failure");
I_scscf_drop();
} else {
xlog("L_DBG", "This is a 401 - keep scscf list to do optimisation");
}
break;
}
}
######################################################################
# Initial requests
######################################################################
route[initial_request]
{
xlog("$$ru => $ru\n");
I_perform_location_information_request("LIR_REPLY", "0");
}
route[LIR_REPLY] {
if ($avp(lia_return_code) == 1) {
if (I_scscf_select("0")) {
xlog("L_DBG", "ru = $ru, du = $du\n");
t_on_reply("initial_request_reply");
t_on_failure("initial_request_failure");
if (!t_relay()) {
t_reply("500","Error forwarding towards S-CSCF");
break;
}
break;
} else {
xlog("L_DBG", "dropping scscf list on initial request");
I_scscf_drop();
t_reply("500", "Server error on LIR select S-CSCF");
break;
}
} else {
t_reply("500", "Server error on LIR");
break;
}
break;
}
######################################################################
# Replies to initial requests
######################################################################
onreply_route[initial_request_reply]
{
xlog("L_DBG", "Enter initial request request block");
if (!t_check_status("(408)")){
xlog("L_DBG", "dropping scscf list on initial request reply");
I_scscf_drop();
}
break;
}
######################################################################
# Failed initial requests
######################################################################
failure_route[initial_request_failure]
{
xlog("L_DBG", "Enter initial request failure block");
if (t_check_status("(408)")){
xlog("L_DBG", "Got a failure for initial request");
if (I_scscf_select("1")) {
t_on_reply("initial_request_reply");
t_on_failure("initial_request_failure");
if (!t_relay()) {
t_reply("500","Error forwarding towards next S-CSCF");
break;
}
break;
} else {
t_reply("500", "Server error on LIR select next S-CSCF");
break;
}
} else {
xlog("L_DBG", "dropping scscf list on initial request failure");
I_scscf_drop();
}
break;
}
#!ifdef PEERING
######################################################################
# HSS returned "User-Unknown" on LIR request
######################################################################
route[lir_term_user_unknown]
{
if (uri =~ "tel:.*") {
# Let's check, if the number can be found in ENUM:
if(!enum_query()) {
# ENUM failed, send it to the PSTN-Gateway:
route(PSTN);
break;
}
# ENUM resolved to another domain
if ($rd != NETWORKNAME) {
t_on_reply("initial_request_reply");
t_on_failure("initial_request_failure");
if (!t_relay()) {
t_reply("500","Error forwarding to external domain");
exit;
};
exit;
} else {
t_reply("604","Does not exist anywhere - HSS User Unknown");
exit;
};
} else {
# we received a request for our domain (non-tel), but HSS said "User Unknown"
if ($rd != NETWORKNAME) {
t_reply("604","Does not exist anywhere - HSS User Unknown");
exit;
} else {
# try to forward non-tel request to other domain
t_on_reply("Initial_Request_reply");
t_on_failure("Initial_Request_failure");
if (!t_relay()) {
t_reply("500","Error forwarding to external domain");
exit;
};
exit;
};
};
}
}
######################################################################
# Send calls to the PSTN-Gateways:
######################################################################
route[PSTN]
{
t_on_failure("PSTN_failure");
# Relay the request towards the PSTN-Gateway:
if (!ds_select_dst("1", "4")) {
send_reply("503", "Service not available");
exit;
}
# Relay the request:
if (!t_relay()) {
send_reply("503", "Service not available");
exit;
};
exit;
}
######################################################################
# manage failure routing cases, perform failover
######################################################################
failure_route[PSTN_failure] {
# Choose another gateway, in case we
# - get a local generated "408"
# - receive a 5xx or 6xx reply from the proxy.
if (t_branch_timeout() || t_check_status("[5-6]..")) {
if (ds_next_dst()) {
# Do Failover in case problems:
t_on_failure("PSTN_failure");
# Relay the request:
if (!t_relay()) {
send_reply("503", "Service not available");
exit;
};
} else {
# Add a header, to indicate the phone should try again in 30 seconds.
append_hf("Retry-After: 30\r\n");
send_reply("503", "Service not available");
}
exit;
}
}
#!endif
#!ifdef FALLBACK_AUTH
######################################################################
# HSS returned "User-Unknown" on UAR request,
# try to send it to any S-CSCF for authentication
######################################################################
route[uar_term_user_unknown]
{
$rd = "scscf."+NETWORKNAME;
t_on_reply("register_reply");
t_on_failure("register_failure");
if (!t_relay()) {
t_reply("500","Error forwarding towards S-CSCF");
break;
}
break;
}
#!endif

View File

@ -0,0 +1,16 @@
# Kamailio - Proxy-CSCF Example Configuration File
Project Website:
* http://www.kamailio.org
## Database Structure
The necessary Database files for the Proxy-CSCF can be found in the utils/kamctl/mysql/ folder.
The following tables (or files) are required:
* ims_dialog-create.sql
* ims_usrloc_pcscf-create.sql
* presence-create.sql
* standard-create.sql

View File

@ -0,0 +1,923 @@
#
# TelcoSuite (V3) Proxy-CSCF
#
# Kamailio SIP Server
# - web: http://www.kamailio.org
# - git: http://sip-router.org
#
# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php
# for an explanation of possible statements, functions and parameters.
#
import_file "pcscf.cfg"
####### Defined Values #########
# *** Value defines - IDs used later in config
#!define DISPATCHER_LIST_SBC 1
#!define DISPATCHER_DST_AVP "i:1"
#!define DISPATCHER_GRP_AVP "i:2"
#!define DISPATCHER_CNT_AVP "i:3"
#!define DISPATCHER_SOCK_AVP "i:4"
#!define RR_CUSTOM_USER_AVP "i:5"
#!define DLG_TIMEOUT_AVP "i:6"
#!define FLT_MOBILE_ORIG 1
#!define FLT_DIALOG 2
#!define FLT_NAT 3
#!define FLT_RTP 4
#!define FLT_CAPTURE 5
####### Global Parameters #########
#!ifdef WITH_DEBUG
debug=4
log_stderror=yes
#!else
debug=2
log_stderror=no
#!endif
memdbg=5
memlog=5
max_while_loops=5000
#!ifdef WITH_XMLRPC
listen=tcp:127.0.0.1:5060
#!endif
# Locks all ser pages into memory making it unswappable (in general one
# doesn't want his sip proxy swapped out )
mlock_pages=yes
# Tries to pre-fault all the shared memory, before starting. When "on", start
# time will increase, but combined with mlock_pages will guarantee ser will get
# all its memory from the beginning (no more kswapd slow downs)
shm_force_alloc=yes
# Do SRV-Loadbalancing:
dns_srv_lb=yes
# Always prefer IPv6:
dns_try_ipv6=yes
# DNS-Based failover
use_dns_failover=yes
# Query NAPTR-Records as well:
dns_try_naptr=no
user_agent_header="User-Agent: TelcoSuite Proxy-CSCF"
server_header="Server: TelcoSuite Proxy-CSCF"
log_facility=LOG_LOCAL0
fork=yes
children=16
#!ifndef TCP_PROCESSES
# Number of TCP Processes
#!define TCP_PROCESSES 16
#!endif
#!ifdef WITH_TLS
# Check, if TCP is enabled:
#!ifndef WITH_TCP
#!define WITH_TCP
#!endif
enable_tls=yes
#!endif
#!ifdef WITH_XMLRPC
#!ifndef WITH_TCP
#!define WITH_TCP
#!endif
#!ifndef TCP_PROCESSES
# Number of TCP Processes
#!define TCP_PROCESSES 3
#!endif
#!endif
#!ifdef WITH_TCP
# life time of TCP connection when there is no traffic
# - a bit higher than registration expires to cope with UA behind NAT
tcp_connection_lifetime=3615
# If a message received over a tcp connection has "alias" in its via a new tcp
# alias port will be created for the connection the message came from (the
# alias port will be set to the via one).
#
# Note: For NAT traversal of TCP clients it is better to not use
# tcp_accept_aliases but just use nathelper module and
# fix_nated_[contact|register] functions.
tcp_accept_aliases=no
# Enable SIP outbound TCP keep-alive using PING-PONG (CRLFCRLF - CRLF).
tcp_crlf_ping=yes
tcp_accept_no_cl=yes
tcp_rd_buf_size=16384
#!ifdef TCP_PROCESSES
tcp_children=TCP_PROCESSES
#!endif
#!else
disable_tcp=yes
#!endif
/* uncomment the next line to disable the auto discovery of local aliases
based on reverse DNS on IPs (default on) */
auto_aliases=no
/* uncomment and configure the following line if you want Kamailio to
bind on a specific interface/port/proto (default bind on all available) */
system.shutdownmode = 0 desc "System shutdown mode"
system.service = "Proxy-CSCF" desc "Function of this server"
####### Modules Section ########
# set paths to location of modules
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
# Fifo Module
# Kamailio Extensions (e.g. MI:uptime, MI:version, cfg:isflagset etc.)
loadmodule "kex"
# Transaction Module
loadmodule "tm"
loadmodule "tmx"
loadmodule "sl"
loadmodule "rr"
loadmodule "pv"
loadmodule "maxfwd"
loadmodule "textops"
loadmodule "textopsx"
# SIP-Utilities: options_reply
loadmodule "siputils"
loadmodule "sanity"
loadmodule "ctl"
loadmodule "cfg_rpc"
loadmodule "xlog"
loadmodule "auth"
loadmodule "dispatcher"
loadmodule "path"
loadmodule "statistics"
loadmodule "ims_dialog"
loadmodule "ims_usrloc_pcscf"
#!ifdef WITH_IPSEC
loadmodule "ims_ipsec_pcscf"
#!endif
loadmodule "ims_registrar_pcscf"
#!ifdef WITH_XMLRPC
loadmodule "xmlrpc"
#!endif
#!ifdef WITH_REGINFO
loadmodule "pua"
#!endif
#!ifdef DB_URL
loadmodule "db_mysql"
#!ifdef DB_URL2
loadmodule "db_cluster"
#!endif
#!endif
#!ifdef WITH_DEBUG
loadmodule "debugger"
#!endif
loadmodule "usrloc"
loadmodule "registrar"
loadmodule "nathelper"
#!ifdef WITH_ANTIFLOOD
loadmodule "pike"
#!endif
#!ifdef WITH_TLS
loadmodule "tls"
#!endif
#!ifdef WITH_RTPPING
loadmodule "rtpping"
#!endif
loadmodule "sdpops"
loadmodule "rtpengine"
#!ifdef WITH_WEBSOCKET
loadmodule "xhttp.so"
loadmodule "websocket.so"
#!endif
#!ifdef WITH_RX
loadmodule "cdp"
loadmodule "cdp_avp"
loadmodule "ims_qos"
#!endif
#!ifdef CAPTURE_NODE
loadmodule "siptrace"
#!endif
#!ifdef WITH_NATPING
loadmodule "rtimer"
loadmodule "uac"
loadmodule "sqlops"
#!endif
# HTable as a cache:
loadmodule "htable"
#!ifdef WITH_DEBUG
loadmodule "debugger.so"
modparam("debugger", "mod_hash_size", 5)
modparam("debugger", "mod_level_mode", 1)
modparam("debugger", "mod_level", "rtpengine=3")
modparam("debugger", "cfgtrace", 1)
#!endif
loadmodule "jsonrpcs.so"
# ----- jsonrpcs params -----
modparam("jsonrpcs", "pretty_format", 1)
/* set the path to RPC fifo control file */
modparam("jsonrpcs", "fifo_name", "/run/kamailio_pcscf/kamailio_rpc.fifo")
/* set the path to RPC unix socket control file */
modparam("jsonrpcs", "dgram_socket", "/run/kamailio_pcscf/kamailio_rpc.sock")
# ----------------- setting module-specific parameters ---------------
#!ifdef DB_URL2
# ----- db_cluster params -----
modparam("db_cluster", "connection", DB_URL)
modparam("db_cluster", "connection", DB_URL2)
modparam("db_cluster", "cluster", "cluster1=>con1=2s2s;con2=1s1s")
#!endif
#!ifdef WITH_ANTIFLOOD
# ----- pike params -----
modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 16)
modparam("pike", "remove_latency", 4)
# ----- htable params -----
# ip ban htable with autoexpire after 5 minutes
modparam("htable", "htable", "ipban=>size=8;autoexpire=300")
modparam("htable", "htable", "failedauth=>size=8;autoexpire=120")
#!endif
modparam("htable", "htable", "contact=>size=8;autoexpire=20")
modparam("htable", "htable", "a=>size=8;autoexpire=20")
#!ifdef WITH_NATPING
modparam("htable", "htable", "natping=>size=8;autoexpire=600000;")
modparam("htable", "htable", "natpingfail=>size=8;autoexpire=600000;")
#!ifdef DB_URL2
modparam("sqlops","sqlcon","pcscf=>cluster://cluster1")
#!else
modparam("sqlops","sqlcon", SQLOPS_DBURL)
#!endif
modparam("uac","restore_mode","none")
# ----------------- Settings for RTimer ---------------
# time interval set to 10 seconds
modparam("rtimer", "timer", "name=NATPING;interval=15;mode=1;")
modparam("rtimer", "exec", "timer=NATPING;route=NATPING")
#!endif
# ----- tm params -----
# auto-discard branches from previous serial forking leg
#modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 3 sec
modparam("tm", "fr_timer", 3000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)
# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 1)
# add a Username to RR-Header
modparam("rr", "add_username", 1)
# Take User from a custom AVP
modparam("rr", "custom_user_avp", "$avp(RR_CUSTOM_USER_AVP)")
#!ifdef WITH_XMLRPC
# ----- xmlrpc params -----
modparam("xmlrpc", "route", "XMLRPC");
modparam("xmlrpc", "url_match", "^/RPC")
#!endif
#!ifdef WITH_TLS
# ----- tls params -----
modparam("tls", "config", "/etc/kamailio_pcscf/tls.cfg")
#!endif
# ----- rtpproxy params -----
modparam("rtpengine", "rtpengine_sock", "1 == udp:localhost:9910")
modparam("rtpengine", "rtpengine_sock", "2 == udp:localhost:9911")
modparam("rtpengine", "setid_avp", "$avp(setid)")
modparam("rtpengine", "extra_id_pv", "$avp(extra_id)")
modparam("path", "use_received", 1)
# ----- ctl params -----
modparam("ctl", "binrpc", "unix:/run/kamailio_pcscf/kamailio_ctl")
# ----------------- Settings for Dispatcher ---------------
modparam("dispatcher", "list_file", "/etc/kamailio_pcscf/dispatcher.list")
#!ifdef WITH_SBC
# Dispatcher: Enable Failover-Support
modparam("dispatcher", "flags", 2)
# Dispatcher: Overwrite Destination address, if required.
modparam("dispatcher", "force_dst", 1)
# AVP's required for Fail-Over-Support:
modparam("dispatcher", "dst_avp", "$avp(DISPATCHER_DST_AVP)")
modparam("dispatcher", "grp_avp", "$avp(DISPATCHER_GRP_AVP)")
modparam("dispatcher", "cnt_avp", "$avp(DISPATCHER_CNT_AVP)")
modparam("dispatcher", "sock_avp", "$avp(DISPATCHER_SOCK_AVP)")
# Try to recover disabled destinations every 15 seconds.
modparam("dispatcher", "ds_ping_interval", 15)
# Actively query the gateways:
modparam("dispatcher", "ds_probing_mode", 1)
#!endif
# -- usrloc params --
#!ifdef DB_URL
#!ifdef DB_URL2
modparam("ims_usrloc_pcscf", "db_url", "cluster://cluster1")
#!else
modparam("ims_usrloc_pcscf", "db_url", DB_URL)
#!endif
modparam("ims_usrloc_pcscf", "db_mode", 1)
#!endif
modparam("ims_usrloc_pcscf", "enable_debug_file", 0)
modparam("ims_usrloc_pcscf", "match_contact_host_port", 1)
modparam("ims_registrar_pcscf", "is_registered_fallback2ip", 1)
modparam("ims_registrar_pcscf", "ignore_reg_state", 1)
modparam("ims_registrar_pcscf", "ignore_contact_rxport_check", 1)
#!ifdef WITH_REGINFO
modparam("ims_registrar_pcscf", "subscribe_to_reginfo", 1)
modparam("ims_registrar_pcscf", "publish_reginfo", 1)
modparam("ims_registrar_pcscf", "pcscf_uri", PCSCF_URL)
#!else
modparam("ims_registrar_pcscf", "subscribe_to_reginfo", 0)
modparam("ims_registrar_pcscf", "publish_reginfo", 0)
#!endif
#!ifdef WITH_IPSEC
modparam("ims_ipsec_pcscf", "ipsec_listen_addr", IPSEC_LISTEN_ADDR)
modparam("ims_ipsec_pcscf", "ipsec_client_port", IPSEC_CLIENT_PORT)
modparam("ims_ipsec_pcscf", "ipsec_server_port", IPSEC_SERVER_PORT)
#!endif
#!ifdef WITH_RX
# -- CDP params --
modparam("cdp","config_file","/etc/kamailio_pcscf/pcscf.xml")
# -- diameter_rx params --
modparam("ims_qos", "rx_dest_realm", "NETWORKNAME")
#!endif
# -- pua params --
#!ifdef WITH_REGINFO
#!ifdef DB_URL
#!ifdef DB_URL2
modparam("pua", "db_url", "cluster://cluster1")
#!else
modparam("pua", "db_url", DB_URL)
#!endif
#!endif
#!endif
# -- ims_dialog params --
modparam("ims_dialog", "dlg_flag", FLT_DIALOG)
modparam("ims_dialog", "timeout_avp", "$avp(DLG_TIMEOUT_AVP)")
modparam("ims_dialog", "detect_spirals", 0)
modparam("ims_dialog", "profiles_no_value", "orig ; term")
#!ifdef DB_URL
#!ifdef DB_URL2
modparam("ims_dialog", "db_url", "cluster://cluster1")
#!else
modparam("ims_dialog", "db_url", DB_URL)
#!endif
modparam("ims_usrloc_pcscf", "db_mode", 1)
#!endif
#!ifdef CAPTURE_NODE
# Destination, where to send the traffic
modparam("siptrace", "duplicate_uri", CAPTURE_NODE)
# Trace all traffic
modparam("siptrace", "trace_on", 1)
modparam("siptrace", "trace_to_database", 0)
modparam("siptrace", "trace_flag", FLT_CAPTURE)
modparam("siptrace", "hep_mode_on", 1)
#!endif
# -- statistics params --
modparam("statistics", "variable", "register_success")
modparam("statistics", "variable", "register_failed")
modparam("statistics", "variable", "register_time")
####### Routing Logic ########
# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
route {
##!ifdef WITH_DEBUG
xlog("$rm ($fu ($si:$sp) to $tu, $ci)\n");
##!endif
#!ifdef WITH_WEBSOCKET
if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) {
xlog("L_WARN", "Websocket-request received on SIP/$Rp\n");
sl_send_reply("403", "Forbidden - Websocket-request received on SIP/$Rp");
exit;
}
#!endif
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
t_relay();
}
exit;
}
if (is_method("NOTIFY") && (uri==myself)) {
route(NOTIFY);
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
# handle retransmissions
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
# Check for Re-Transmissions
t_check_trans();
if (is_method("UPDATE")) {
send_reply("403","Forbidden - Target refresh outside dialog not allowed");
break;
}
if (is_method("BYE|PRACK")) {
send_reply("403","Forbidden - Originating subsequent requests outside dialog not allowed");
break;
}
loose_route();
#!ifdef WITH_SBC
if (ds_is_from_list(DISPATCHER_LIST_SBC)) {
if (is_method("INVITE")) {
if (is_present_hf("C-Params")) {
remove_hf("Contact");
remove_hf("C-Params");
append_hf("Contact: $ct;$hdr(C-Params)\r\n");
}
if ($route_uri =~ "sip:mo@.*") {
# prepend mo as user for record route
$avp(RR_CUSTOM_USER_AVP)="mo";
if (is_present_hf("P-Route")) {
$du = $(hdr(P-Route){nameaddr.uri});
remove_hf("P-Route");
append_hf("Route: $hdr(P-Route)\r\n");
}
t_on_reply("SBC_GET_CPARAMS");
}
if ($route_uri =~ "sip:mt@.*") {
$du = $ru;
handle_ruri_alias();
if ($rc == 1) {
setflag(FLT_NAT);
}
xlog("$$dP => $(dP{s.tolower}) ($du)\n");
# prepend mo as user for record route
$avp(RR_CUSTOM_USER_AVP)="mt";
if ($(dP{s.tolower}) == "tls") {
route(ENC_SRTP);
} else if ($(dP{s.tolower}) == "ws") {
# Even WSS is incorrectly shown as WS
route(ENC_WSS_RTP);
} else if ($(dP{s.tolower}) == "wss") {
route(ENC_WSS_RTP);
} else {
route(ENC_RTP);
}
# Handle NAT
route(NATMANAGE);
# Handle Mobile Terminated requests
route(MT);
}
}
if (is_method("REGISTER")) {
append_hf("Path: <sip:term@$Ri:$Rp;lr>\r\n");
}
} else {
#!endif
if ($route_uri =~ "sip:term@.*") {
#!ifdef WITH_SBC
#!ifdef WITH_SBC_CALL
if (is_method("INVITE")) {
#!endif
if (!strempty($(ct{tobody.params}))) {
append_hf("C-Params: $(ct{tobody.params})\r\n");
}
append_hf("SBC: mt\r\n");
# Do some Round-Robin on the SBC's
t_on_failure("SBC_failure");
# Choose an SBC to send the call to:
if (!ds_select_dst(DISPATCHER_LIST_SBC, "4")) {
send_reply("503", "Service Unavailable (SBC failure)");
exit;
}
#!ifdef WITH_SBC_CALL
}
#!endif
#!else
handle_ruri_alias();
if ($dP == "tls") {
route(ENC_SRTP);
} else if ($dP == "ws") {
route(ENC_WS_RTP);
} else if ($dP == "wss") {
route(ENC_WSS_RTP);
} else {
route(ENC_RTP);
}
if ($rc == 1) {
setflag(FLT_NAT);
}
# Handle NAT
route(NATMANAGE);
# prepend mo as user for record route
$avp(RR_CUSTOM_USER_AVP)="mt";
route(MT);
#!endif
} else {
force_rport();
if(is_method("INVITE|SUBSCRIBE|UPDATE|REGISTER")) {
add_contact_alias();
}
setflag(FLT_NAT);
if (is_method("REGISTER")) {
route(REGISTER);
exit;
}
# prepend mo as user for record route
$avp(RR_CUSTOM_USER_AVP)="mo";
# Set Flag for MO:
setflag(FLT_MOBILE_ORIG);
# Increase timer for inbound requests, we may have to do failover:
t_set_fr(120000, 30000);
route(MO);
if (is_method("INVITE")) {
# SRTP in RTP übersetzen
if ($pr == "tls") {
route(DEC_SRTP);
} else if ($pr == "ws") {
route(DEC_WS_RTP);
} else if ($pr == "wss") {
route(DEC_WSS_RTP);
} else {
route(DEC_RTP);
}
# Handle NAT
route(NATMANAGE);
}
#!ifdef WITH_SBC
#!ifdef WITH_SBC_CALL
if (is_method("INVITE")) {
#!endif
# Apply changes to this message
msg_apply_changes();
# Copy Route-Header:
append_hf("P-Route: $hdr(Route)\r\n");
if (!strempty($(ct{tobody.params}))) {
append_hf("C-Params: $(ct{tobody.params})\r\n");
}
append_hf("SBC: mo\r\n");
# Do some Round-Robin on the SBC's
t_on_failure("SBC_failure");
# Choose an SBC to send the call to:
if (!ds_select_dst(DISPATCHER_LIST_SBC, "4")) {
send_reply("503", "Service Unavailable (SBC failure)");
exit;
}
#!endif
#!ifdef WITH_SBC_CALL
}
#!endif
}
#!ifdef WITH_SBC
}
#!endif
if (is_method("INVITE|SUBSCRIBE")) {
# record routing for dialog forming requests (in case they are routed)
record_route();
}
# Forward request:
route(RELAY);
exit;
}
route[SBC_GET_CPARAMS] {
if (!strempty($(ct{tobody.params}))) {
append_hf("C-Params: $(ct{tobody.params})\r\n");
}
}
# Per SIP request initial checks
route[REQINIT] {
# Reply to OPTIONS:
if (is_method("OPTIONS") && (uri==myself)) {
options_reply();
exit;
}
$var(used) = 1 - ($stat(free_size) / $stat(total_size));
xlog("L_DBG", "Mem: Total $stat(total_size), Free $stat(free_size) [$var(used)% used]\n");
if ($var(used) > 95) {
send_reply("503", "Server overloaded");
exit;
}
# Trace this message
#!ifdef CAPTURE_NODE
sip_trace();
setflag(FLT_CAPTURE);
#!endif
#!ifdef WITH_ANTIFLOOD
# flood dection from same IP and traffic ban for a while
# be sure you exclude checking trusted peers, such as pstn gateways
# - local host excluded (e.g., loop to self)
if (!has_totag() && (src_ip!=myself) && !ds_is_from_list())
{
if($sht(ipban=>$si)!=$null)
{
# ip is already blocked
xlog("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
xlog("Blocking traffic from $si\n");
exit;
}
if (!pike_check_req()) {
xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp, $ua)\n");
xlog("Blocking traffic from $si\n");
$sht(ipban=>$si) = 1;
exit;
}
}
if ((uri == myself) && is_method("INVITE|REGISTER")) {
xlog("L_ALERT","ALERT: Request to myself: $ru from $fu (IP:$si:$sp, $ua), Blocking\n");
xlog("Blocking traffic from $si\n");
$sht(ipban=>$si) = 1;
exit;
}
#!endif
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7")) {
xlog("Malformed SIP message from $si:$sp\n");
exit;
}
# Check for shutdown mode:
if (!has_totag() && ($sel(cfg_get.system.shutdownmode) > 0)) {
send_reply("503", "Server shutting down");
exit;
}
if (!is_method("REGISTER")) {
ipsec_forward("location");
}
# Ignore Re-Transmits:
if (t_lookup_request()) {
exit;
}
if (is_method("INVITE|REGISTER")) {
send_reply("100", "Trying");
}
}
route[RELAY] {
if (!t_relay()) {
sl_reply_error();
}
exit;
}
# Handle requests within SIP dialogs
route[WITHINDLG] {
if (has_totag()) {
if(!isdsturiset()) {
handle_ruri_alias();
}
if ( is_method("ACK") && ($sht(contact=>$ci) != $null) ) {
xlog("Contact of Reply: $sht(contact=>$ci) ($ci)\n");
$ru = $sht(contact=>$ci);
}
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if ($route_uri =~ "sip:mt@.*") {
route(MT_indialog);
} else {
route(MO_indialog);
}
# Handle NAT
route(NATMANAGE);
route(RELAY);
} else {
if ( is_method("ACK") ) {
xlog("Contact of Reply: $T_rpl($ct)\n");
if ( t_check_trans() ) {
# no 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;
}
}
sl_send_reply("404","Not here");
}
exit;
}
}
######################################################################
# Negative replies to REGISTER requests:
######################################################################
failure_route[SBC_failure] {
#!ifdef WITH_IPBLOCK
if (is_method("REGISTER") && !ds_is_from_list()) {
if (t_check_status("403|[5-6][0-9][0-9]")) {
if ($sht(failedauth=>$si) != $null)
$sht(failedauth=>$si) = $sht(failedauth=>$si) + 1;
else
$sht(failedauth=>$si) = 1;
if ($sht(failedauth=>$si) > 10) {
xlog("L_ALERT","ALERT: blocking $rm from $fu (IP:$si:$sp), more than 5 failed auth requests!\n");
xlog("Blocking traffic from $si\n");
$sht(ipban=>$si) = 1;
}
}
}
#!endif
# Choose another gateway, in case we
# - get a local generated "408"
# - receive a 5xx or 6xx reply from the proxy.
if (t_branch_timeout() || t_check_status("[5-6]..")) {
if (ds_next_dst()) {
# Do Failover in case problems:
t_on_failure("SBC_failure");
t_relay();
} else {
# Add a header, to indicate the phone should try again in 30 seconds.
append_hf("Retry-After: 30\r\n");
send_reply("504", "Server Time-Out");
}
exit;
}
}
# Notify Route: #
#####################################################################
route[NOTIFY]
{
xlog("L_DBG", "IMS: INSIDE NOTIFY\n");
if (reginfo_handle_notify("location")) {
send_reply("200","OK - P-CSCF processed notification");
break;
} else {
t_reply("500","Error encountered while processing notification");
break;
}
}
# NATPING Route: #
#####################################################################
route[NATPING] {
route(preload_pcscf);
sht_iterator_start("nat_iterator", "natping");
while(sht_iterator_next("nat_iterator")) {
xlog("OPTIONS to $shtitval(nat_iterator) via $shtitkey(nat_iterator)...\n");
$uac_req(method) = "OPTIONS";
$uac_req(ruri) = $shtitval(nat_iterator);
$uac_req(furi) = PCSCF_URL;
$uac_req(turi) = $shtitval(nat_iterator);
$uac_req(ouri) = $shtitkey(nat_iterator);
$uac_req(evroute) = 1;
uac_req_send();
}
sht_iterator_end("nat_iterator");
}
event_route[uac:reply] {
#!ifdef WITH_DEBUG
xlog("request sent to $uac_req(ruri) completed with code: $uac_req(evcode), Type $uac_req(evtype)\n");
#!endif
if (($uac_req(evtype) != 1) || ($uac_req(evcode) != 200)) {
if ($sht(natpingfail=>$uac_req(ouri)) == $null) {
$sht(natpingfail=>$uac_req(ouri)) = 1;
} else {
$sht(natpingfail=>$uac_req(ouri)) = $sht(natpingfail=>$uac_req(ouri)) + 1;
}
# xlog(" request sent to $uac_req(ruri): Fail Counter is $sht(natpingfail=>$uac_req(ouri))\n");
if ($sht(natpingfail=>$uac_req(ouri)) > 3) {
if ($(uac_req(ouri){uri.transport}) == "tcp") {
$var(alias) = "alias="+$(uac_req(ouri){uri.host})+"~"+$(uac_req(ouri){uri.port})+"~2";
} else if ($(uac_req(ouri){uri.transport}) == "tls") {
$var(alias) = "alias="+$(uac_req(ouri){uri.host})+"~"+$(uac_req(ouri){uri.port})+"~3";
} else {
$var(alias) = "alias="+$(uac_req(ouri){uri.host})+"~"+$(uac_req(ouri){uri.port})+"~1";
}
xlog(" Unregistering $uac_req(ruri);$var(alias)\n");
setdebug("9");
ipsec_destroy("location");
pcscf_unregister("location", "$uac_req(ruri);$var(alias)", "$(uac_req(ouri){uri.host})", "$(uac_req(ouri){uri.port})");
resetdebug();
$sht(natping=>$uac_req(ouri)) = $null;
$sht(natpingfail=>$uac_req(ouri)) = $null;
}
} else {
$sht(natpingfail=>$uac_req(ouri)) = $null;
}
}
event_route[htable:expired:natping] {
xlog("natping record expired $shtrecord(key) => $shtrecord(value)\n");
}
event_route[htable:mod-init] {
xlog("event_route[htable:mod-init] {\n");
}
route[preload_pcscf] {
if ($shv(preload_pcscf) == 1) return;
$shv(preload_pcscf) = 1;
sql_query("pcscf", "select aor, received, received_port, received_proto from location;", "resultset");
xlog("Preloading NAT-PING. Rows: $dbr(resultset=>rows)\n");
if($dbr(resultset=>rows)>0) {
$var(i) = 0;
while($var(i) < $dbr(resultset=>rows)) {
$var(ouri) = "sip:"+$dbr(resultset=>[$var(i),1])+":"+$dbr(resultset=>[$var(i),2]);
if ($dbr(resultset=>[$var(i),3]) == 2) {
$var(ouri) = $var(ouri)+";transport=tcp";
} else if ($dbr(resultset=>[$var(i),3]) == 3) {
$var(ouri) = $var(ouri)+";transport=tls";
}
$var(noalias) = $(dbr(resultset=>[$var(i),0]){re.subst,/^(.*);alias=.*/\1/}{nameaddr.uri});
# xlog("$$var(noalias) => $var(noalias) (via $var(ouri))\n");
$sht(natping=>$var(ouri)) = $var(noalias);
$var(i) = $var(i) + 1;
}
}
sql_result_free("resultset");
}
#!ifdef WITH_XMLRPC
include_file "route/xmlrpc.cfg"
#!endif
#!ifdef WITH_WEBSOCKET
include_file "route/websocket.cfg"
#!endif
include_file "route/register.cfg"
include_file "route/rtp.cfg"
include_file "route/mo.cfg"
include_file "route/mt.cfg"

View File

@ -0,0 +1,235 @@
######################################################################
# Originating, Intial Requests
######################################################################
route[MO]
{
# Strip Transport from RURI:
$ru = $(ru{re.subst,/;transport=[A-Za-z]*//g});
# Process route headers, if any:
loose_route();
if (!pcscf_is_registered("location")) {
send_reply("403","Forbidden - You must register first with a S-CSCF");
exit;
}
# We do not trust the user, let's remove the P-Asserted-Identity, if any:
remove_hf("P-Asserted-Identity");
remove_hf("P-Preferred-Identity");
# Add P-Charging-Vector
sip_p_charging_vector("g");
if (is_present_hf("P-Preferred-Identity") && pcscf_assert_identity("location", "$hdr(P-Preferred-Identity)")) {
append_hf("P-Asserted-Identity: $hdr(P-Preferred-Identity)\r\n");
} else if (is_present_hf("P-Asserted-Identity") && pcscf_assert_identity("location", "$hdr(P-Asserted-Identity)")) {
append_hf("P-Asserted-Identity: $hdr(P-Asserted-Identity)\r\n");
} else if (pcscf_assert_identity("location", "$(fu{tobody.uri})")) {
append_hf("P-Asserted-Identity: <$(fu{tobody.uri})>\r\n");
} else {
append_hf("P-Asserted-Identity: <$pcscf_asserted_identity>\r\n");
}
if (!pcscf_follows_service_routes("location")){
#Variant 1 - deny access to the network
#send_reply("400","Bad Request - Not following indicated service routes");
#break;
#Variant 2 - enforce routes and let the dialog continue
pcscf_force_service_routes("location");
}
# add IBCF/THIG route here if required
# Check for "sec-agree" in the Require header:
if (is_present_hf("Require") && $hdr(Require) =~ ".*sec-agree.*") {
# Remove the old Require-Header:
remove_hf("Require");
# Replace ", sec-agree" with ""
$var(new_hdr) = $(hdr(Require){re.subst,/[, ]*sec-agree//gi});
if ($(var(new_hdr){s.len}) > 0) {
append_hf("Require: $var(new_hdr)\r\n");
}
}
# Check for "sec-agree" in the Proxy-Require header:
if (is_present_hf("Proxy-Require") && $hdr(Proxy-Require) =~ ".*sec-agree.*") {
# Remove the old Proxy-Require-Header:
remove_hf("Proxy-Require");
# Replace ", sec-agree" with ""
$var(new_hdr) = $(hdr(Proxy-Require){re.subst,/[, ]*sec-agree//gi});
if ($(var(new_hdr){s.len}) > 0) {
append_hf("Proxy-Require: $var(new_hdr)\r\n");
}
}
remove_hf("Security-Verify");
#!ifdef TRF_FUNCTION
$var(trf) = TRF_FUNCTION;
# Check for "sec-agree" in the Proxy-Require header:
if (is_present_hf("Feature-Caps")) {
# Remove the old Proxy-Require-Header:
remove_hf("Feature-Caps");
append_hf("Feature-Caps: $hdr(Feature-Caps);+g.3gpp.trf=\"<sip:$var(trf);lr>\"\r\n");
} else {
append_hf("Feature-Caps: *;+g.3gpp.trf=\"<sip:$var(trf);lr>\"\r\n");
}
#!endif
# Add a visited Network-ID-Header:
if (is_present_hf("P-Visited-Network-ID")) {
$var(new_hdr) = "NETWORKNAME, "+$hdr(P-Visited-Network-ID);
append_hf("P-Visited-Network-ID: $var(new_hdr)\r\n");
} else {
append_hf("P-Visited-Network-ID: NETWORKNAME\r\n");
}
t_on_reply("MO_reply");
}
######################################################################
# Replies to Originating Initial Requests
######################################################################
onreply_route[MO_reply] {
if (is_present_hf("C-Params")) {
remove_hf("Contact");
remove_hf("C-Params");
append_hf("Contact: $ct;$hdr(C-Params)\r\n");
}
#!ifdef WITH_IPSEC
ipsec_forward("location");
#!endif
# In case of 1xx and 2xx do NAT
if(status=~"[12][0-9][0-9]")
route(NATMANAGE);
#!ifdef WITH_RX
if (t_check_status("183")){
xlog("L_DBG", "IMS: Received 183/200 inside orig_initial_reply\n");
if (t_is_retr_async_reply()) {
xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n");
drop();
}
xlog("L_DBG","Diameter: Orig authorizing media via Rx\n");
$avp(FTAG_CUSTOM_AVP)=$ft;
$avp(TTAG_CUSTOM_AVP)=$tt;
$avp(CALLID_CUSTOM_AVP)=$ci;
$var(aarret) = Rx_AAR("MO_aar_reply","orig","",-1);
xlog("L_DBG", "AAR return code is $var(aarret)\n");
switch ($var(aarret)) {
case 1:
#suspend was successful and we must break
xlog("L_DBG", "Success sending AAR for media\n");
exit;
case -1:
#this is retransmitted response so we just drop it
xlog("L_DBG", "AAR still processing dropping retransmitted response\n");
drop();
exit;
default:
xlog("L_ERR", "Unable to send AAR for media\n");
#comment this if you want to allow even if Rx fails
dlg_terminate("all", "Sorry no QoS available");
exit;
}
}
}
route[MO_aar_reply]
{
#this is async so to know status we have to check the reply avp
switch ($avp(s:aar_return_code)) {
case 1:
xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n");
break;
default:
xlog("L_ERR", "IMS: AAR failed Orig\n");
xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)");
xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)");
xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)");
#comment this if you want to allow even if Rx fails
if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){