herlesupreeth / Open5gs_Config

Open5gs Configuration files for IMS/VoLTE
3 stars 2 forks source link

SQN? #8

Closed ghost closed 3 years ago

ghost commented 3 years ago

Dear @herlesupreeth, Hi

Today i tried to connect two UE ( Samsung A20 and iphone 6 ) to VOLTE Network I also followed your instruction System is Fresh Ubuntu when i install all the components for the first time and configuring HSS there was no SQN there! and when i finished following ur instruction in the last part there was some SQN parameter and i did put it to all 0 because there was no previous UE connected to the network! putting zero for SQN is right?

after that when i connected the UE to the EPC i had internet connection but there was No sign of VOLTE on the UE ( in the past when i tested ur instruction with the same UE (Samsung A20) there was VOLTE sign! But now there is no sign of it! Unfortunately i forgot to trace my packets and i just have access to logs right now!

My questions are as Follows: How can i change SQN when FOHSS is not connecting to UE ( Waiting for Authentication!!)? what SQN number should i put in SQN field? Can u please check the Logs for troubleshooting?

These are some images and after that Some Logs:

image

image

image

image

image

image

image

image

SQN

Can u point out How can i set SQN ? because here in this pictures i can SQN has 3 number ex. 418 in HSS but in the FOHSS it is 000000000083 !!! or in some others 000000000005a2 or any other thing!

image

Iphone i think, got connected to FOHSS [ i can see registered but it doesnt have any sign of VOLTE ) and when i eject the sim from iphone and insert it into Samsung A20 ( which 1 months ago got connected to the network and has VOLTE sign ) Now can not connect and has no sign of VOLTE ]

Here are some logs:

ghost commented 3 years ago

MME.txt PCRF.txt PGW.txt SgW.txt FOHSS.txt HSS.txt Kamailio ICSCF.txt Kamailio PCSCF.txt Kamailio SCSCF.txt

herlesupreeth commented 3 years ago

Iphone i think, got connected to FOHSS [ i can see registered but it doesnt have any sign of VOLTE ) and when i eject the sim from iphone and insert it into Samsung A20 ( which 1 months ago got connected to the network and has VOLTE sign ) Now can not connect and has no sign of VOLTE ]

For this Goto CoIMS app --> Samsung IMS settings --> Click on Reset to Default Now, make sure ims APN is present in the APN settings of the phone. If its not there create it Then, retry

My questions are as Follows: How can i change SQN when FOHSS is not connecting to UE ( Waiting for Authentication!!)? what SQN number should i put in SQN field? Can u please check the Logs for troubleshooting?

Issue an RTR from IMPI section for that IMSI in Fhoss and retry

ghost commented 3 years ago

Iphone i think, got connected to FOHSS [ i can see registered but it doesnt have any sign of VOLTE ) and when i eject the sim from iphone and insert it into Samsung A20 ( which 1 months ago got connected to the network and has VOLTE sign ) Now can not connect and has no sign of VOLTE ]

For this Goto CoIMS app --> Samsung IMS settings --> Click on Reset to Default Now, make sure ims APN is present in the APN settings of the phone. If its not there create it Then, retry

My questions are as Follows: How can i change SQN when FOHSS is not connecting to UE ( Waiting for Authentication!!)? what SQN number should i put in SQN field? Can u please check the Logs for troubleshooting?

Issue an RTR from IMPI section for that IMSI in Fhoss and retry

Dear @herlesupreeth Thanks But I didn't use CoIMS ever, Not now and not the last time which could see Volte Sign on UE!

Can u tell me more precisely? U meant here? image and can u tell me which one to select in Apply for and Reason?

Thanks Best regards

herlesupreeth commented 3 years ago

U meant here?

Yep, in here select REASON as Remove S-CSCF or something must be there

But I didn't use CoIMS ever, Not now and not the last time which could see Volte Sign on UE!

Then, I cannot help as I dont have much knowledge on the UE side

ghost commented 3 years ago

Hello again @herlesupreeth

I did install it! and also did remove S-CSCF

volte.zip

But i couldnt connect! i can see unauthorized UE!

Can u check traces?

ghost commented 3 years ago

what should i do in order to sync SQN in Both HSS and FOHSS! They are not the same in size!

SQN in HSS has 3 # but SQN in FOHSS has 12 # !!! What's the problem! and how can i handle it?

herlesupreeth commented 3 years ago

@modyngs Its definitely not an issue of SQN, even if there is an SQN mismatch the FhoSS will handle it just fine.

I believe there is something wrong with IMS setup, i see the 40 Un-authorized and then the TCP packets to IPSec ports but no successful there. So I would suggest you take all the latest commits from kamailio (https://github.com/herlesupreeth/kamailio) - recompile and all then take latest commits from https://github.com/herlesupreeth/Kamailio_IMS_Config and give it a try

ghost commented 3 years ago

Dear @herlesupreeth I did try all the latest commit! just used open5gs v1.3 and your configs ( https://github.com/herlesupreeth/Open5gs_Confi) 4G commit

But the problem still there

ghost commented 3 years ago

the latest branch of this (https://github.com/herlesupreeth/kamailio) is 5.3 right?

herlesupreeth commented 3 years ago

the latest branch of this (https://github.com/herlesupreeth/kamailio) is 5.3 right?

Yes, thats right.

Send me a pcap so that I can help

ghost commented 3 years ago

oh, Sorry i just see ur message Before that i thought this might be related to Core! because has some errors in MME So i opened an issue in here https://github.com/open5gs/open5gs/issues/777#issue-795108686

herlesupreeth commented 3 years ago

Can you do a git branch for FHoSS and send me the output?

ghost commented 3 years ago

Sure, root@voi:~# cd /opt/OpenIMSCore root@voi:/opt/OpenIMSCore# cd FHoSS/ root@voi:/opt/OpenIMSCore/FHoSS# git branch

root@voi:/opt/OpenIMSCore/FHoSS# git checkout M config/DiameterPeerHSS.xml M config/hibernate.properties M config/hss.properties M scripts/userdata.sql M src-web/WEB-INF/web.xml Your branch is up to date with 'origin/master'.

ghost commented 3 years ago

Dear @herlesupreeth I also Added a new IMSI in HSS and also in FHoSS and New isim card! but still the same! some thing like this happened in FHoss Screenshot (56)

which waiting for authentication! not registered

herlesupreeth commented 3 years ago

In the Fhoss logs you posted in this issue (https://github.com/open5gs/open5gs/issues/777#issue-795108686) i see the following logs

image

As per the latest commit in Fhoss i dont have these logs which makes me suspect that you have some modified version of Fhoss. In the latest version of Fhoss I have provided a fix which works even in case of SQN mismatch between the open5gs HSS and Fhoss

herlesupreeth commented 3 years ago

Also, you have the following logs in various components

PCSCF image

ICSCF image

Which make suspect whether the connection between (ICSCF and Fhoss) is proper or not

ghost commented 3 years ago

Ok, but as i pasted the exact command i use the master branch of FHoSS i can see the Master branch is for about 5 months ago I did cloned it from git clone https://github.com/herlesupreeth/FHoSS

herlesupreeth commented 3 years ago

I would suggest to take a fresh copy of Fhoss alone, re-compile and use it

In the meantime you can check the SQN in open5gs Web UI and enter the same value in Fhoss Web UI SQN field and see if it attaches or not

ghost commented 3 years ago

Right Now i'm Doing all the Proccess from scratch in the new instance Screenshot (57)

Also right Now i'm doing clone of : cd ~ && git clone https://github.com/herlesupreeth/Kamailio_IMS_Config

the whole network which my Router is in here has 192.168.100.0/24 address My OpenStack has 192.168.100.3 my instance ( Vo2) has 10.4.128.23 for internal Address and 10.20.20.206 for Floating Ip address

the eNB is on my laptop which has 192.168.100.4 ip address and i'm gonna set Ip address for UEs like 192.168.110.0 and 192.168.111.0

Am i doing sth wrong ip networking? Also i'll change all the configs to be like yours in tutorial

ghost commented 3 years ago

Also one thing i saw u mentioned in https://github.com/herlesupreeth/Kamailio_IMS_Config that For VoLTE setup, make sure to have eNB and (EPC + IMS) machines are in the same subnet according to the above post am i doing right?

ghost commented 3 years ago

I would suggest to take a fresh copy of Fhoss alone, re-compile and use it

In the meantime you can check the SQN in open5gs Web UI and enter the same value in Fhoss Web UI SQN field and see if it attaches or not

About Putting the Same SQN from HSS to FHoSS how can i ? because as i mentioned in https://github.com/herlesupreeth/Open5gs_Config/issues/8#issuecomment-766090465 and https://github.com/herlesupreeth/Open5gs_Config/issues/8#issue-781436881 the SQN size in FHoSS is not Compatible with HSS SQN size! How should i manage this?

ghost commented 3 years ago

right now i'm changing Configs $sudo nano kamailio_icscf/icscf.cfg

# SIP / UDP
listen=udp:10.4.128.23:4060
#listen=udp:10.4.128.23:4060 advertise 10.20.20.206:4060
# SIP / TCP
listen=tcp:10.4.128.23:4060
#listen=tcp:10.4.128.23:4060 advertise 10.20.20.206:4060
# SIP / TCP/TLS
#listen=tls:11.22.33.44:4061

alias=ims.mnc001.mcc001.3gppnetwork.org

#!define NETWORKNAME "ims.mnc001.mcc001.3gppnetwork.org"
#!define HOSTNAME "icscf.ims.mnc001.mcc001.3gppnetwork.org"

#!subst "/NETWORKNAME/ims.mnc001.mcc001.3gppnetwork.org/"

#!define ENUM_SUFFIX "ims.mnc001.mcc001.3gppnetwork.org."

# SIP-Address of capturing node, if not set, capturing is disabled.
##!define CAPTURE_NODE "sip:127.0.0.1:9060"

# Connection URL for the database:
#!define DB_URL "mysql://icscf:heslo@localhost/icscf"
##!define DB_URL2 "con2=>mysql://icscf:heslo@127.0.0.1/icscf"

# Allowed IPs for XML-RPC-Queries
##!define XMLRPC_WHITELIST_1 "127.0.0.1"
##!define XMLRPC_WHITELIST_2 "127.0.0.1"
##!define XMLRPC_WHITELIST_3 "127.0.0.1"

# *** To run in debug mode:
#     - define WITH_DEBUG
#
# *** To enable TLS support execute:
#     - adjust CFGDIR/tls.cfg as needed
#     - define WITH_TLS
#
# *** To enable XMLRPC support execute:
#     - define WITH_XMLRPC
#     - adjust route[XMLRPC] for access policy
#
# *** To enable a Homer SIP-Capter-Node:
#     - define CAPTURE_NODE with a proper address
#
# *** To forwarding to PSTN for unknown users:
#     - define PEERING
#
# Enabled Features for this host:
##!define WITH_DEBUG
#!define WITH_TCP
##!define WITH_TLS
#!define WITH_XMLRPC
##!define PEERING
##!define FALLBACK_AUTH

$sudo nano kamailio_icscf/icscf.xml

<?xml version="1.0" encoding="UTF-8"?>
<DiameterPeer
        FQDN="icscf.ims.mnc001.mcc001.3gppnetwork.org"
        Realm="ims.mnc001.mcc001.3gppnetwork.org"
        Vendor_Id="10415"
        Product_Name="CDiameterPeer"
        AcceptUnknownPeers="1"
        DropUnknownOnDisconnect="1"
        Tc="30"
        Workers="16"
        QueueLength="32"
        TransactionTimeout="5"
        SessionsHashSize="128"
        DefaultAuthSessionTimeout="3600"
        MaxAuthSessionTimeout="3600"
>

        <Peer FQDN="hss.ims.mnc001.mcc001.3gppnetwork.org" Realm="ims.mnc001.mcc001.3gppnetwork.org" port="3868"/>

        <Acceptor port="3869" bind="10.4.128.23"/>

        <Auth id="16777216" vendor="10415"/><!-- 3GPP Cx -->
        <Auth id="16777216" vendor="4491"/><!-- CableLabs Cx -->
        <Auth id="16777216" vendor="13019"/><!-- ETSI/TISPAN Cx -->
        <Auth id="16777216" vendor="0"/><!-- ETSI/TISPAN Cx -->

        <!--
                Supported Vendor IDs - list of values which will be sent in the CER/CEA in the
                Supported-Vendor-ID AVPs
        -->
        <SupportedVendor vendor="10415" />

        <DefaultRoute FQDN="hss.ims.mnc001.mcc001.3gppnetwork.org" metric="10"/>
</DiameterPeer>

$sudo nano kamailio_pcscf/kamailio_pcscf.cfg


#
# TelcoSuite (V3) Proxy-CSCF
#
# Kamailio (OpenSER) 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=4

#!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=36000
# 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_reuse_port=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

#phone2tel=1

udp_mtu = 1300
udp_mtu_try_proto = TCP

/* 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/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/:/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/:/usr/lib/x86_64-linux-gnu/kamailio/modules/:/usr/local/lib64/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 "sctp"
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", "mod_level", "ims_qos=3")
modparam("debugger", "mod_level", "ims_ipsec_pcscf=3")
modparam("debugger", "mod_level", "textops=3")
modparam("debugger", "mod_level", "tm=3")
modparam("debugger", "mod_level", "ims_registrar_pcscf=3")
modparam("debugger", "mod_level", "ims_usrloc_pcscf=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", "/var/run/kamailio_pcscf/kamailio_rpc.fifo")
/* set the path to RPC unix socket control file */
modparam("jsonrpcs", "dgram_socket", "/var/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")
modparam("htable", "htable", "natpingfrom=>size=8;autoexpire=600000;")
#!endif

modparam("htable", "htable", "contact=>size=8;autoexpire=20")
modparam("htable", "htable", "a=>size=8;autoexpire=20")

#!ifdef WITH_IMS_HDR_CACHE
modparam("htable", "htable", "serviceroutes=>size=16;autoexpire=14400;")
modparam("htable", "htable", "associateduris=>size=16;autoexpire=14400;")
#!endif

#!ifdef WITH_NATPING
modparam("htable", "htable", "natping=>size=8;autoexpire=600000;")
modparam("htable", "htable", "natpingfail=>size=8;autoexpire=600000;")
modparam("htable", "htable", "natpingfrom=>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 60 seconds
modparam("rtimer", "timer", "name=NATPING;interval=60;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)
# Dont reply automatically with "100 Trying"
modparam("tm", "auto_inv_100", 0)

# ----- 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", "setid_default", 1)
modparam("rtpengine", "rtpengine_sock", "1 == udp:localhost:2223")
#modparam("rtpengine", "rtpengine_sock", "2 == udp:localhost:2224")
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:/var/run/kamailio_pcscf/kamailio_ctl")

# ----------------- Settings for Dispatcher ---------------
modparam("dispatcher", "list_file", "/etc/kamailio_pcscf/dispatcher.list")

# 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)")

#modparam("dispatcher", "xavp_dst", "$avp(DISPATCHER_DST_AVP)")
#modparam("dispatcher", "xavp_dst_mode", 0)
#modparam("dispatcher", "xavp_ctx", "$avp(DISPATCHER_CNT_AVP)")
#modparam("dispatcher", "xavp_ctx_mode", 0)

# Try to recover disabled destinations every 15 seconds.
modparam("dispatcher", "ds_ping_interval", 15)
# Actively query the gateways:
modparam("dispatcher", "ds_probing_mode", 1)

# -- 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", 0)
#!endif
#modparam("ims_usrloc_pcscf", "hashing_type", 2)
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)
modparam("ims_registrar_pcscf", "pending_reg_expires", 30)
modparam("ims_registrar_pcscf", "subscription_expires", 36000)
modparam("ims_usrloc_pcscf", "expires_grace", 36000)

#!ifdef WITH_REGINFO
modparam("ims_registrar_pcscf", "subscribe_to_reginfo", 1)
modparam("ims_registrar_pcscf", "publish_reginfo", 1)
modparam("ims_registrar_pcscf", "pcscf_uri", "sip:HOSTNAME")
#!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)
modparam("ims_ipsec_pcscf", "ipsec_spi_id_start", 4096)
modparam("ims_ipsec_pcscf", "ipsec_max_connections", IPSEC_MAX_CONN)
modparam("htable", "htable", "ipsec_clients=>size=8;autoexpire=600000;")
#!endif

#!ifdef WITH_RX
# -- CDP params --
modparam("cdp","config_file","/etc/kamailio_pcscf/pcscf.xml")
# -- diameter_rx params --
modparam("ims_qos", "rx_dest_realm", "PCRF_REALM")
#modparam("ims_qos", "rx_forced_peer", "pcrf.epc.mnc001.mcc001.3gppnetwork.org")
#modparam("ims_qos", "rx_forced_peer", "10.4.128.23")
#modparam("ims_qos", "rx_dest_realm", "NETWORKNAME")
modparam("ims_qos", "early_qosrelease_reason", "Sorry - QoS failed")
modparam("ims_qos", "confirmed_qosrelease_headers", "X-Reason: QoS failed\r\n")
modparam("ims_qos", "authorize_video_flow", 1)
modparam("ims_qos", "af_signaling_ip", RX_AF_SIGNALING_IP)
modparam("ims_qos", "include_rtcp_fd", 1)
modparam("ims_qos", "rx_auth_expiry", 36000)
#!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_dialog", "db_mode", 0)
#!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
        xnotice("PCSCF: $rm $ru ($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 retransmissions
        if (!is_method("ACK")) {
                if(t_precheck_trans()) {
                        t_check_trans();
                        exit;
                }
        }
        #t_check_trans();

        # Check for Re-Transmissions
        t_check_trans();

        # handle requests within SIP dialogs
        route(WITHINDLG);

        ### only initial requests (no To tag)

        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;
        }

        #Set DLG flag to track dialogs using dialog2
        if (!is_method("REGISTER|SUBSCRIBE"))
                setflag(FLT_DIALOG);

        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;
        }
#!ifdef WITH_IPSEC
        if (!is_method("REGISTER")) {
        ipsec_forward("location");
  }
#!endif
        # 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()) {
                xnotice("Within DLG\n");
                # sequential request withing a dialog should
                # take the path determined by record-routing
                if (loose_route()) {
                        xnotice("Within loose route\n");
                        if(!isdsturiset()) {
                                handle_ruri_alias();
                                #if ($rc == 1) {
                                #       $ru = "sip:" + $rU + "@" + $dd + ":" + $dp + ";transport=" + $rP;
                                #}
                        }

                        if ( is_method("ACK") && ($sht(contact=>$ci) != $null) ) {
                                xlog("Contact of Reply: $sht(contact=>$ci) ($ci)\n");
                                $ru = $sht(contact=>$ci);
                        }

                        if ($route_uri =~ "sip:mt@.*") {
                                route(MT_indialog);
                        } else {
                                route(MO_indialog);
                        }

                        # Handle NAT
                        route(NATMANAGE);

                        route(RELAY);
                        exit;
                }
                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;
        }
}

#!ifdef WITH_NATPING
# NATPING Route:                                                    #
#####################################################################
route[NATPING] {
        route(preload_pcscf);

        sht_lock("natping=>natpinglock");
        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(sock) = $sht(natpingfrom=>$shtitkey(nat_iterator));
                $uac_req(turi) = $shtitval(nat_iterator);
                $uac_req(ouri) = $shtitkey(nat_iterator);
                $uac_req(evroute) = 1;
                uac_req_send();
        }
        sht_iterator_end("nat_iterator");
        sht_unlock("natping=>natpinglock");
}

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)) > 30) {
                        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");
#!ifdef WITH_IPSEC
                        #if ($sht(ipsec_clients=>$(T_req($ct){nameaddr.uri})) != $null) {
                                #ipsec_destroy("location");
                                ipsec_destroy_by_contact("location", "$uac_req(ruri);$var(alias)", "$(uac_req(ouri){uri.host})", "$(uac_req(ouri){uri.port})");
                        #}
#!endif
                        pcscf_unregister("location", "$uac_req(ruri);$var(alias)", "$(uac_req(ouri){uri.host})", "$(uac_req(ouri){uri.port})");
                        resetdebug();
                        sht_lock("natping=>natpinglock");
                        $sht(natping=>$uac_req(ouri)) = $null;
                        sht_unlock("natping=>natpinglock");
                        $sht(natpingfail=>$uac_req(ouri)) = $null;

                        sht_lock("natpingfrom=>natpingfromlock");
                        $sht(natpingfrom=>$uac_req(ouri)) = $null;
                        sht_unlock("natpingfrom=>natpingfromlock");
                        $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_lock("natping=>natpinglock");
                        $sht(natping=>$var(ouri)) = $var(noalias);
                        sht_unlock("natping=>natpinglock");
                        $var(i) = $var(i) + 1;
                }
        }
        sql_result_free("resultset");
}
#!endif

#!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"
ghost commented 3 years ago

$sudo nano kamailio_pcscf/pcscf.xml

<?xml version="1.0" encoding="UTF-8"?>
<DiameterPeer
        FQDN="pcscf.ims.mnc001.mcc001.3gppnetwork.org"
        Realm="ims.mnc001.mcc001.3gppnetwork.org"
        Vendor_Id="10415"
        Product_Name="CDiameterPeer"
        AcceptUnknownPeers="1"
        DropUnknownOnDisconnect="1"
        Tc="30"
        Workers="4"
        QueueLength="8"
        TransactionTimeout="5"
        SessionsHashSize="128"
        DefaultAuthSessionTimeout="3600"
        MaxAuthSessionTimeout="3600"
>
        <Peer FQDN="pcrf.epc.mnc001.mcc001.3gppnetwork.org" Realm="epc.mnc001.mcc001.3gppnetwork.org" port="3868"/>

        <Acceptor port="3871" bind="10.4.128.23"/>

        <Auth id="16777236" vendor="10415"/> <!-- 3GPP Rx -->
        <Auth id="16777236" vendor="0"/> <!-- 3GPP Rx -->

        <DefaultRoute FQDN="pcrf.epc.mnc001.mcc001.3gppnetwork.org" metric="10"/>

</DiameterPeer>

$sudo nano kamailio_pcscf/pcscf.cfg


#
# TelcoSuite (V3) Proxy-CSCF
#
# Kamailio (OpenSER) 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=4

#!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=36000
# 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_reuse_port=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

#phone2tel=1

udp_mtu = 1300
udp_mtu_try_proto = TCP

/* 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/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/:/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/:/usr/lib/x86_64-linux-gnu/kamailio/modules/:/usr/local/lib64/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 "sctp"
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", "mod_level", "ims_qos=3")
modparam("debugger", "mod_level", "ims_ipsec_pcscf=3")
modparam("debugger", "mod_level", "textops=3")
modparam("debugger", "mod_level", "tm=3")
modparam("debugger", "mod_level", "ims_registrar_pcscf=3")
modparam("debugger", "mod_level", "ims_usrloc_pcscf=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", "/var/run/kamailio_pcscf/kamailio_rpc.fifo")
/* set the path to RPC unix socket control file */
modparam("jsonrpcs", "dgram_socket", "/var/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")
modparam("htable", "htable", "natpingfrom=>size=8;autoexpire=600000;")
#!endif

modparam("htable", "htable", "contact=>size=8;autoexpire=20")
modparam("htable", "htable", "a=>size=8;autoexpire=20")

#!ifdef WITH_IMS_HDR_CACHE
modparam("htable", "htable", "serviceroutes=>size=16;autoexpire=14400;")
modparam("htable", "htable", "associateduris=>size=16;autoexpire=14400;")
#!endif

#!ifdef WITH_NATPING
modparam("htable", "htable", "natping=>size=8;autoexpire=600000;")
modparam("htable", "htable", "natpingfail=>size=8;autoexpire=600000;")
modparam("htable", "htable", "natpingfrom=>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 60 seconds
modparam("rtimer", "timer", "name=NATPING;interval=60;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)
# Dont reply automatically with "100 Trying"
modparam("tm", "auto_inv_100", 0)

# ----- 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", "setid_default", 1)
modparam("rtpengine", "rtpengine_sock", "1 == udp:localhost:2223")
#modparam("rtpengine", "rtpengine_sock", "2 == udp:localhost:2224")
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:/var/run/kamailio_pcscf/kamailio_ctl")

# ----------------- Settings for Dispatcher ---------------
modparam("dispatcher", "list_file", "/etc/kamailio_pcscf/dispatcher.list")

# 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)")

#modparam("dispatcher", "xavp_dst", "$avp(DISPATCHER_DST_AVP)")
#modparam("dispatcher", "xavp_dst_mode", 0)
#modparam("dispatcher", "xavp_ctx", "$avp(DISPATCHER_CNT_AVP)")
#modparam("dispatcher", "xavp_ctx_mode", 0)

# Try to recover disabled destinations every 15 seconds.
modparam("dispatcher", "ds_ping_interval", 15)
# Actively query the gateways:
modparam("dispatcher", "ds_probing_mode", 1)

# -- 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", 0)
#!endif
#modparam("ims_usrloc_pcscf", "hashing_type", 2)
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)
modparam("ims_registrar_pcscf", "pending_reg_expires", 30)
modparam("ims_registrar_pcscf", "subscription_expires", 36000)
modparam("ims_usrloc_pcscf", "expires_grace", 36000)

#!ifdef WITH_REGINFO
modparam("ims_registrar_pcscf", "subscribe_to_reginfo", 1)
modparam("ims_registrar_pcscf", "publish_reginfo", 1)
modparam("ims_registrar_pcscf", "pcscf_uri", "sip:HOSTNAME")
#!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)
modparam("ims_ipsec_pcscf", "ipsec_spi_id_start", 4096)
modparam("ims_ipsec_pcscf", "ipsec_max_connections", IPSEC_MAX_CONN)
modparam("htable", "htable", "ipsec_clients=>size=8;autoexpire=600000;")
#!endif

#!ifdef WITH_RX
# -- CDP params --
modparam("cdp","config_file","/etc/kamailio_pcscf/pcscf.xml")
# -- diameter_rx params --
modparam("ims_qos", "rx_dest_realm", "PCRF_REALM")
#modparam("ims_qos", "rx_forced_peer", "pcrf.epc.mnc001.mcc001.3gppnetwork.org")
#modparam("ims_qos", "rx_forced_peer", "10.4.128.23")
#modparam("ims_qos", "rx_dest_realm", "NETWORKNAME")
modparam("ims_qos", "early_qosrelease_reason", "Sorry - QoS failed")
modparam("ims_qos", "confirmed_qosrelease_headers", "X-Reason: QoS failed\r\n")
modparam("ims_qos", "authorize_video_flow", 1)
modparam("ims_qos", "af_signaling_ip", RX_AF_SIGNALING_IP)
modparam("ims_qos", "include_rtcp_fd", 1)
modparam("ims_qos", "rx_auth_expiry", 36000)
#!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_dialog", "db_mode", 0)
#!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
        xnotice("PCSCF: $rm $ru ($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 retransmissions
        if (!is_method("ACK")) {
                if(t_precheck_trans()) {
                        t_check_trans();
                        exit;
                }
        }
        #t_check_trans();

        # Check for Re-Transmissions
        t_check_trans();

        # handle requests within SIP dialogs
        route(WITHINDLG);

        ### only initial requests (no To tag)

        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;
        }

        #Set DLG flag to track dialogs using dialog2
        if (!is_method("REGISTER|SUBSCRIBE"))
                setflag(FLT_DIALOG);

        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;
        }
#!ifdef WITH_IPSEC
        if (!is_method("REGISTER")) {
        ipsec_forward("location");
  }
#!endif
        # 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()) {
                xnotice("Within DLG\n");
                # sequential request withing a dialog should
                # take the path determined by record-routing
                if (loose_route()) {
                        xnotice("Within loose route\n");
                        if(!isdsturiset()) {
                                handle_ruri_alias();
                                #if ($rc == 1) {
                                #       $ru = "sip:" + $rU + "@" + $dd + ":" + $dp + ";transport=" + $rP;
                                #}
                        }

                        if ( is_method("ACK") && ($sht(contact=>$ci) != $null) ) {
                                xlog("Contact of Reply: $sht(contact=>$ci) ($ci)\n");
                                $ru = $sht(contact=>$ci);
                        }

                        if ($route_uri =~ "sip:mt@.*") {
                                route(MT_indialog);
                        } else {
                                route(MO_indialog);
                        }

                        # Handle NAT
                        route(NATMANAGE);

                        route(RELAY);
                        exit;
                }
                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;
        }
}

#!ifdef WITH_NATPING
# NATPING Route:                                                    #
#####################################################################
route[NATPING] {
        route(preload_pcscf);

        sht_lock("natping=>natpinglock");
        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(sock) = $sht(natpingfrom=>$shtitkey(nat_iterator));
                $uac_req(turi) = $shtitval(nat_iterator);
                $uac_req(ouri) = $shtitkey(nat_iterator);
                $uac_req(evroute) = 1;
                uac_req_send();
        }
        sht_iterator_end("nat_iterator");
        sht_unlock("natping=>natpinglock");
}

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)) > 30) {
                        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");
#!ifdef WITH_IPSEC
                        #if ($sht(ipsec_clients=>$(T_req($ct){nameaddr.uri})) != $null) {
                                #ipsec_destroy("location");
                                ipsec_destroy_by_contact("location", "$uac_req(ruri);$var(alias)", "$(uac_req(ouri){uri.host})", "$(uac_req(ouri){uri.port})");
                        #}
#!endif
                        pcscf_unregister("location", "$uac_req(ruri);$var(alias)", "$(uac_req(ouri){uri.host})", "$(uac_req(ouri){uri.port})");
                        resetdebug();
                        sht_lock("natping=>natpinglock");
                        $sht(natping=>$uac_req(ouri)) = $null;
                        sht_unlock("natping=>natpinglock");
                        $sht(natpingfail=>$uac_req(ouri)) = $null;

                        sht_lock("natpingfrom=>natpingfromlock");
                        $sht(natpingfrom=>$uac_req(ouri)) = $null;
                        sht_unlock("natpingfrom=>natpingfromlock");
                        $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_lock("natping=>natpinglock");
                        $sht(natping=>$var(ouri)) = $var(noalias);
                        sht_unlock("natping=>natpinglock");
                        $var(i) = $var(i) + 1;
                }
        }
        sql_result_free("resultset");
}
#!endif

#!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"
root@vo2:~/Kamailio_IMS_Config#

root@vo2:~/Kamailio_IMS_Config#
root@vo2:~/Kamailio_IMS_Config#
root@vo2:~/Kamailio_IMS_Config# sudo nano kamailio_pcscf/pcscf.xml

root@vo2:~/Kamailio_IMS_Config# sudo nano kamailio_pcscf/pcscf.cfg
root@vo2:~/Kamailio_IMS_Config# sudo cat kamailio_pcscf/pcscf.cfg
# IP-Adress for incoming SIP-Traffic, in the following format:

# SIP / UDP
listen=udp:10.4.128.23:5060
# Uncomment the below line only when UE is behind double NAT (e.g. VoIP calling over WiFi/ CN behind a NAT)
#listen=udp:10.4.128.23:5060 advertise 10.20.20.206:5060
# SIP / TCP
listen=tcp:10.4.128.23:5060
# Uncomment the below line only when UE is behind double NAT (e.g. VoIP calling over WiFi/ CN behind a NAT)
#listen=tcp:10.4.128.23:5060 advertise 10.20.20.206:5060
# SIP / TCP/TLS
#listen=tls:11.22.33.44:5061

# IPSEC / UDP
#!define IPSEC_LISTEN_ADDR "10.4.128.23"
#!define IPSEC_CLIENT_PORT 5100
#!define IPSEC_SERVER_PORT 6100
#!define IPSEC_MAX_CONN 10

# IP used in Rx_AAR_Register - IP of this P-CSCF, to be used in the flow for the AF-signaling
#!define RX_AF_SIGNALING_IP "10.4.128.23"
# Uncomment the below line only when UE is behind double NAT (e.g. VoIP calling over WiFi/ CN behind a NAT)
##!define RX_AF_SIGNALING_IP "10.20.20.206"

alias=pcscf.ims.mnc001.mcc001.3gppnetwork.org

#!define MY_WS_PORT 80
#!define MY_WSS_PORT 443

#!define PCSCF_URL "sip:pcscf.ims.mnc001.mcc001.3gppnetwork.org:5060"

#!define TCP_PROCESSES 8

#!subst "/NETWORKNAME/ims.mnc001.mcc001.3gppnetwork.org/"
#!subst "/HOSTNAME/pcscf.ims.mnc001.mcc001.3gppnetwork.org/"
#!subst "/PCRF_REALM/epc.mnc001.mcc001.3gppnetwork.org/"

# SIP-Address of capturing node, if not set, capturing is disabled.
##!define CAPTURE_NODE "sip:127.0.0.1:9060"

# Allowed IPs for XML-RPC-Queries
##!define XMLRPC_WHITELIST_1 "127.0.0.1"
##!define XMLRPC_WHITELIST_2 "127.0.0.1"
##!define XMLRPC_WHITELIST_3 "127.0.0.1"

# Databases:
#!define DB_URL "mysql://pcscf:heslo@127.0.0.1/pcscf"
##!define DB_URL2 "con2=>mysql://pcscf:heslo@127.0.0.1/pcscf"

#!define SQLOPS_DBURL "pcscf=>mysql://pcscf:heslo@127.0.0.1/pcscf"

#! Optional: Server-URL for Websocket-Requests
##!define WEBSOCKET_WEBSERVER "phone.ng-voice.com"

##!define TRF_FUNCTION "trf.ims.mnc001.mcc001.3gppnetwork.org"

#
# Several features can be enabled using '#!define WITH_FEATURE' directives:
#
# *** To run in debug mode:
#     - define WITH_DEBUG
#
# *** To enable nat traversal execute:
#     - define WITH_NAT
#     - define the connection to the RTP-Proxy: RTPPROXY_ADDRESS
#
# *** To force alls calls through the RTP-Proxy
#     - this will automagically enable NAT-Traversal
#     - define FORCE_RTPRELAY
#
# *** To enable IPv4/IPv6 Translation (RTPProxy)
#     - this will automagically enable NAT-Traversal
#     - define WITH_RTPIPV4
#
# *** To enable TCP support execute:
#     - define WITH_TCP
#
# *** To enable TLS support execute:
#     - adjust CFGDIR/tls.cfg as needed
#     - define WITH_TLS
#     - this will automagically enable TCP
#
# *** To enable XMLRPC support execute:
#     - define WITH_XMLRPC
#     - this will automagically enable TCP
#
# *** To enable anti-flood detection execute:
#     - adjust pike and htable=>ipban settings as needed (default is
#       block if more than 16 requests in 2 seconds and ban for 300 seconds)
#     - define WITH_ANTIFLOOD
#
# *** To enable the Rx-Interface:
#     - Configure Rx-Diameter-Interface in pcscf.xml
#     - define WITH_RX
#
# *** To enable a Homer SIP-Capter-Node:
#     - define CAPTURE_NODE with a proper address
#
# *** To enable support for the SEMS-SBC
#     - define WITH_SBC
#     - configure dispatcher-list with a set of SBC's

#
# Enabled Features for this host:
##!define WITH_DEBUG
#!define WITH_NAT
#!define WITH_NATPING
#!define FORCE_RTPRELAY
##!define WITH_TLS
##!define WITH_XMLRPC
##!define WITH_IPBLOCK
##!define WITH_ANTIFLOOD
#!define WITH_RX
#!define WITH_RX_REG
#!define WITH_RX_CALL
#!define WITH_TCP
##!define WITH_RTPIPV4
##!define WITH_SBC
##!define WITH_SBC_CALL
##!define WITH_REGINFO
##!define WITH_RTPPING
##!define WITH_WEBSOCKET
#!define WITH_IPSEC
#!define WITH_IMS_HDR_CACHE
#!define WITH_PING_UDP
#!define WITH_PING_TCP
ghost commented 3 years ago

$sudo nano kamailio_scscf/scscf.cfg


# SIP / UDP
listen=udp:10.4.128.23:6060
#listen=udp:10.4.128.23:6060 advertise 10.20.20.206:6060
# SIP / TCP
listen=tcp:10.4.128.23:6060
#listen=tcp:10.4.128.23:6060 advertise 10.20.20.206:6060
# SIP / TCP/TLS
#listen=tls:11.22.33.44:6061

#!define NETWORKNAME "ims.mnc001.mcc001.3gppnetwork.org"
#!define NETWORKNAME_ESC "ims\.mnc001\.mcc001\.3gppnetwork\.org"
#!define HOSTNAME "scscf.ims.mnc001.mcc001.3gppnetwork.org"
#!define HOSTNAME_ESC "scscf\.ims\.mnc001\.mcc001\.3gppnetwork\.org"
#!define URI "sip:scscf.ims.mnc001.mcc001.3gppnetwork.org:6060"

#!subst "/NETWORKNAME/ims.mnc001.mcc001.3gppnetwork.org/"

alias=scscf.ims.mnc001.mcc001.3gppnetwork.org

# ENUM-Server to query:
#!define ENUM_SUFFIX "ims.mnc001.mcc001.3gppnetwork.org."

# SIP-Address of capturing node, if not set, capturing is disabled.
##!define CAPTURE_NODE "sip:127.0.0.1:9060"

# Connection URL for the database:
# For use with a single database:
#!define DB_URL "mysql://scscf:heslo@127.0.0.1/scscf"

# For use with DB_Cluster: con1 (primary), con2 (backup)
##!define DB_URL "con1=>mysql://scscf:heslo@127.0.0.1/scscf"
##!define DB_URL2 "con2=>mysql://scscf:heslo@127.0.0.1/scscf"

# Select Authorization Algorhithm:
##!define REG_AUTH_DEFAULT_ALG "AKAv1-MD5"
##!define REG_AUTH_DEFAULT_ALG "AKAv2-MD5"
##!define REG_AUTH_DEFAULT_ALG "MD5"
##!define REG_AUTH_DEFAULT_ALG "CableLabs-Digest"
##!define REG_AUTH_DEFAULT_ALG "3GPP-Digest"
##!define REG_AUTH_DEFAULT_ALG "TISPAN-HTTP_DIGEST_MD5"
# Let the HSS decide
#!define REG_AUTH_DEFAULT_ALG "HSS-Selected"

# Number of TCP Processes
#!define TCP_PROCESSES 3

##!define RO_FORCED_PEER "32260@3gpp.org"
#!define RO_DESTINATION "hssocs.voiceblue.com"
#!define RO_ROOT "32260@3gpp.org"
#!define RO_EXT "ext"
#!define RO_MNC "02"
#!define RO_MCC "001"
#(see https://en.wikipedia.org/wiki/Mobile_country_code_(MCC))
#!define RO_RELEASE "8"
# See http://tools.ietf.org/html/rfc4006#section-4.1.2 for the definition of the Service-Context

##!define XMLRPC_WHITELIST_1 "127.0.0.1"
##!define XMLRPC_WHITELIST_2 "127.0.0.1"
##!define XMLRPC_WHITELIST_3 "127.0.0.1"

# Several features can be enabled using '#!define WITH_FEATURE' directives:
#
# *** To run in debug mode:
#     - define WITH_DEBUG
#
# *** To enable TCP support execute:
#     - define WITH_TCP
#
# *** To enable XMLRPC support execute:
#     - define WITH_XMLRPC
#     - this will automagically enable TCP
#
# *** To enable the Ro-Interface:
#     - Configure Ro-Diameter-Interface in scscf.xml
#     - define WITH_RO
#
# *** To enable a Homer SIP-Capter-Node:
#     - define CAPTURE_NODE with a proper address
#
# Enabled Features for this host:
##!define WITH_DEBUG
#!define WITH_TCP
##!define WITH_XMLRPC
##!define WITH_RO
##!define WITH_RO_TERM
#!define WITH_AUTH

$sudo nano kamailio_scscf/scscf.xml


<?xml version="1.0" encoding="UTF-8"?>
<DiameterPeer
        FQDN="scscf.ims.mnc001.mcc001.3gppnetwork.org"
        Realm="ims.mnc001.mcc001.3gppnetwork.org"
        Vendor_Id="10415"
        Product_Name="CDiameterPeer"
        AcceptUnknownPeers="1"
        DropUnknownOnDisconnect="1"
        Tc="30"
        Workers="16"
        QueueLength="32"
        TransactionTimeout="5"
        SessionsHashSize="128"
        DefaultAuthSessionTimeout="3600"
        MaxAuthSessionTimeout="3600"
>
        <Peer FQDN="hss.ims.mnc001.mcc001.3gppnetwork.org" Realm="ims.mnc001.mcc001.3gppnetwork.org" port="3868"/>

        <Acceptor port="3870" bind="10.4.128.23"/>

        <Auth id="16777216" vendor="10415"/><!-- 3GPP Cx -->
        <Auth id="16777216" vendor="4491"/><!-- CableLabs Cx -->
        <Auth id="16777216" vendor="13019"/><!-- ETSI/TISPAN Cx -->
        <Auth id="16777216" vendor="0"/><!-- ETSI/TISPAN Cx -->

        <Auth id="4" vendor="10415"/> <!--3GPP Ro -->
        <Acct id="4" vendor="10415" />

        <!--
                Supported Vendor IDs - list of values which will be sent in the CER/CEA in the
                Supported-Vendor-ID AVPs
        -->
        <SupportedVendor vendor="10415" />

        <DefaultRoute FQDN="hss.ims.mnc001.mcc001.3gppnetwork.org" metric="10"/>
</DiameterPeer>
herlesupreeth commented 3 years ago

Any reason for using OpenStack for deploying EPC + IMS? As you might have read OpenStack is NOT needed if you want to have EPC + IMS setup.

Another thing.. please do not paste large config files here in the issue its hard to get valuable information out of an issue. I would suggest to attach as file rather than pasting the code

About Putting the Same SQN from HSS to FHoSS how can i ? because as i mentioned in #8 (comment) and #8 (comment) the SQN size in FHoSS is not Compatible with HSS SQN size! How should i manage this?

Append the zero at the start according to the length of SQN in Fhoss

ghost commented 3 years ago

Any reason for using OpenStack for deploying EPC + IMS? As you might have read OpenStack is NOT needed if you want to have EPC + IMS setup.

I followed ur tutorial on VOLTE there are some networking like internal Ip and Floating Ips, So i installed Openstack! is that problem?

Another thing.. please do not paste large config files here in the issue its hard to get valuable information out of an issue. I would suggest to attach as file rather than pasting the code

Ok sorry for that,

Append the zero at the start according to the length of SQN in Fhoss

Yeah i did that but the problem remains!

herlesupreeth commented 3 years ago

I followed ur tutorial on VOLTE there are some networking like internal Ip and Floating Ips, So i installed Openstack! is that problem?

If that is the case, then dont use OpenStack. I would rather suggest to use the https://github.com/herlesupreeth/docker_open5gs this repo.

If you just execute the following steps and edit the .env file you would have a working setup in less than 30 min no headache of all the configuration steps in VoLTE tutorial. Just do these steps on bare machine

  1. https://github.com/herlesupreeth/docker_open5gs#build-and-execution-instructions
  2. https://github.com/herlesupreeth/docker_open5gs#build-and-run-using-docker-compose
ghost commented 3 years ago

Yeah i tested the Docker its great

Now i'm gonna test using openstack can u help me on that?

ghost commented 3 years ago

Dear @herlesupreeth in some part of Tutorial u said

Finally, make sure of the following in Open5GS

PCO options which indicate the address of the Proxy-CSCF Need to indicate support for Voice-over-Packet-Switched (VoPS) in NAS message to UE from EPC

How can i do those?

herlesupreeth commented 3 years ago

How can i do those?

If the UE tried for IMS attach PCO options would be set by UE, regarding the second point its done by default in open5gs

ghost commented 3 years ago

Thanks

Now when i run PCRF for the first time i have such error: 01/28 09:52:38.191: [diam] ERROR: ../subprojects/freeDiameter/libfdcore/p_psm.c:630 ERROR: in '(fd_p_ce_msgrcv(&msg, (hdr->msg_flags & 0x80), peer))' : Invalid argument (../lib/diameter/common/init.c:116)

Whats that for? I installed Diameter Screenshot (58)

herlesupreeth commented 3 years ago

Now when i run PCRF for the first time i have such error: 01/28 09:52:38.191: [diam] ERROR: ../subprojects/freeDiameter/libfdcore/p_psm.c:630 ERROR: in '(fd_p_ce_msgrcv(&msg, (hdr->msg_flags & 0x80), peer))' : Invalid argument (../lib/diameter/common/init.c:116)

you can ignore it. As long as PCRF says its connected to P-CSCF all good (it will connect eventually)

herlesupreeth commented 3 years ago

Closing this issue as its not related to SQN mismatch