1205 lines
35 KiB
INI
1205 lines
35 KiB
INI
#
|
|
# 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=on
|
|
# Always prefer IPv6:
|
|
dns_try_ipv6=on
|
|
# Always prefer IPv6:
|
|
dns_cache_flags=4
|
|
# DNS-Based failover
|
|
use_dns_failover=on
|
|
# Query NAPTR-Records as well:
|
|
dns_try_naptr=off
|
|
# DNS cache won't be used (all dns lookups will result into a DNS request)
|
|
use_dns_cache=off
|
|
|
|
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=UE_SUBSCRIPTION_EXPIRES
|
|
# 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"
|
|
# Following module is required even in case of IPSec being disabled.
|
|
loadmodule "ims_ipsec_pcscf"
|
|
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 WITH_N5
|
|
loadmodule "http_client"
|
|
loadmodule "jansson"
|
|
loadmodule "nghttp2"
|
|
loadmodule "uuid"
|
|
#!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")
|
|
#!ifdef WITH_IPSEC
|
|
modparam("debugger", "mod_level", "ims_ipsec_pcscf=3")
|
|
#!endif
|
|
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/kamailio_rpc.fifo")
|
|
/* set the path to RPC unix socket control file */
|
|
modparam("jsonrpcs", "dgram_socket", "/var/run/kamailio/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=UE_SUBSCRIPTION_EXPIRES;")
|
|
#!endif
|
|
|
|
modparam("htable", "htable", "a=>size=8;autoexpire=20")
|
|
|
|
#!ifdef WITH_IMS_HDR_CACHE
|
|
modparam("htable", "htable", "serviceroutes=>size=16;autoexpire=UE_SUBSCRIPTION_EXPIRES;")
|
|
modparam("htable", "htable", "associateduris=>size=16;autoexpire=UE_SUBSCRIPTION_EXPIRES;")
|
|
#!endif
|
|
|
|
#!ifdef WITH_NATPING
|
|
modparam("htable", "htable", "natping=>size=8;autoexpire=UE_SUBSCRIPTION_EXPIRES;")
|
|
modparam("htable", "htable", "natpingfail=>size=8;autoexpire=UE_SUBSCRIPTION_EXPIRES;")
|
|
modparam("htable", "htable", "natpingfrom=>size=8;autoexpire=UE_SUBSCRIPTION_EXPIRES;")
|
|
#!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=5;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)")
|
|
modparam("rr", "force_send_socket", 1)
|
|
|
|
#!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:RTPENGINE_IP: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/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", UE_SUBSCRIPTION_EXPIRES)
|
|
modparam("ims_registrar_pcscf", "delete_delay", CONTACT_DELETE_DELAY)
|
|
modparam("ims_usrloc_pcscf", "expires_grace", 120)
|
|
|
|
#!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("ims_ipsec_pcscf", "ipsec_preferred_ealg", "null")
|
|
modparam("htable", "htable", "ipsec_clients=>size=8;autoexpire=UE_SUBSCRIPTION_EXPIRES;")
|
|
#!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", "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", UE_SUBSCRIPTION_EXPIRES)
|
|
modparam("ims_qos", "recv_mode", 1)
|
|
modparam("ims_qos", "dialog_direction", RX_IMS_REG_DIALOG_DIRECTION)
|
|
#!endif
|
|
|
|
#!ifdef WITH_N5
|
|
|
|
# Tables to store users and their session details
|
|
modparam("htable", "htable", "user_data=>size=8;autoexpire=3600;")
|
|
modparam("htable", "htable", "user_ids=>size=8;autoexpire=3600;")
|
|
modparam("htable", "htable", "user_sdps_ip=>size=8;autoexpire=3600;")
|
|
modparam("htable", "htable", "user_sdps_port=>size=8;autoexpire=3600;")
|
|
modparam("htable", "htable", "user_sdps_rtcp_port=>size=8;autoexpire=3600;")
|
|
modparam("htable", "htable", "user_sip_ips=>size=8;autoexpire=3600;")
|
|
modparam("htable", "htable", "user_sip_ports=>size=8;autoexpire=3600;")
|
|
|
|
# HTTP2 for 5G -- Modules Parameters
|
|
modparam("http_client", "httpredirect", 1)
|
|
modparam("http_client", "useragent", "AF")
|
|
modparam("http_client", "maxdatasize", 64535)
|
|
modparam("http_client", "connection_timeout", 2)
|
|
modparam("http_client", "keep_connections", 1)
|
|
modparam("http_client", "response_headers", 1)
|
|
modparam("http_client", "query_result", 1)
|
|
modparam("nghttp2", "listen_addr", "N5_BIND_IP")
|
|
modparam("nghttp2", "listen_port", "N5_BIND_PORT")
|
|
# Replace the following with your own Key and Cert, you can use HAProxy to terminate TLS towards Clients e.g. Open5gs PCF
|
|
# modparam("nghttp2", "tls_private_key", "/mnt/pcscf/http2_key.pem")
|
|
# modparam("nghttp2", "tls_public_key", "/mnt/pcscf/http2_tr.pem")
|
|
|
|
modparam("rtimer", "timer", "name=NRF_NFM;interval=5;mode=1;")
|
|
modparam("rtimer", "exec", "timer=NRF_NFM;route=NRF_NFM")
|
|
#!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")
|
|
modparam("ims_dialog", "profiles_with_value", "caller ; callee")
|
|
#!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")
|
|
|
|
# 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);
|
|
|
|
#!ifdef WITH_IPSEC
|
|
if (is_request() && is_method("REGISTER")) {
|
|
sht_lock("ipsec_clients=>ipsec_clients_lock");
|
|
$sht(ipsec_clients=>$si) = $null;
|
|
if ($hdrc(Security-Client) == 1) {
|
|
$sht(ipsec_clients=>$si) = 1;
|
|
}
|
|
sht_unlock("ipsec_clients=>ipsec_clients_lock");
|
|
}
|
|
#!endif
|
|
|
|
# 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|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;
|
|
}
|
|
|
|
# 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 ($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")) {
|
|
xnotice("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
|
|
xnotice("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)) > 10) {
|
|
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
|
|
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("L_INFO", "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_N5
|
|
|
|
# 5G N5 HTTP2 Server routing script basic code
|
|
event_route[nghttp2:request] {
|
|
xinfo("request: $nghttp2(method) - url: $nghttp2(path) - data: [$nghttp2(data)]\n");
|
|
|
|
# Check if the requested URL is /nf-status-notify
|
|
if ($nghttp2(path) == "/nf-status-notify") {
|
|
nghttp2_reply_header("Content-Type", "text/html");
|
|
nghttp2_reply_header("Server:", "AF");
|
|
nghttp2_reply("200", "<html><body>PCF registered at PCSCF</body></html>");
|
|
} else if ($nghttp2(path) == "/terminate") {
|
|
nghttp2_reply_header("accept", "application/json");
|
|
nghttp2_reply_header("accept", "application/problem+json");
|
|
nghttp2_reply_header("Content-Type", "application/json");
|
|
nghttp2_reply_header("Server", "AF");
|
|
nghttp2_reply("204", "No Content");
|
|
} else {
|
|
# Optionally handle other URLs or do nothing
|
|
nghttp2_reply_header("accept", "application/json");
|
|
nghttp2_reply_header("accept", "application/problem+json");
|
|
nghttp2_reply_header("Content-Type", "application/json");
|
|
nghttp2_reply_header("Server", "AF");
|
|
nghttp2_reply("404", "Not Found");
|
|
}
|
|
}
|
|
|
|
route[NRF_NFM] {
|
|
if ($var(n5_hb_fail_count) > 5) {
|
|
xlog("L_ERR", "PCSCF NF no longer registered at SCP. Re-attempting registration!!\n");
|
|
$var(n5_initalized) = 0;
|
|
}
|
|
|
|
$var(time_now) = $_s($timef(%a, %d %b %Y %H:%M:%S %Z));
|
|
|
|
# TODO: Send at heartbeat intervals received in reponse to NF registration
|
|
if ($var(n5_initalized) == 1) {
|
|
# Send Heartbeat
|
|
$var(nf_hb_headers) = "content-type: application/json-patch+json\r\n";
|
|
$var(nf_hb_headers) = $var(nf_hb_headers) + "accept: application/json,application/problem+json\r\n";
|
|
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n";
|
|
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-max-rsp-time: 10000\r\n";
|
|
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-discovery-service-names: nnrf-nfm\r\n";
|
|
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now);
|
|
|
|
$var(nf_hb_json_body) ='[]';
|
|
$var(nf_hb_body) = '{
|
|
"op": "replace",
|
|
"path": "/nfStatus",
|
|
"value": "REGISTERED"
|
|
}';
|
|
jansson_append("obj", "", $var(nf_hb_body), "$var(nf_hb_json_body)");
|
|
$var(nf_hb_body) = '{
|
|
"op": "replace",
|
|
"path": "/load",
|
|
"value": 0
|
|
}';
|
|
jansson_append("obj", "", $var(nf_hb_body), "$var(nf_hb_json_body)");
|
|
|
|
http_client_request_v2pk("PATCH", "http://SCP_BIND_IP:SCP_BIND_PORT/nnrf-nfm/v1/nf-instances/$var(pcscf_uuid)", "$var(nf_hb_json_body)", "$var(nf_hb_headers)", "$var(nf_hb_result)");
|
|
switch ($rc) {
|
|
case 204:
|
|
$var(n5_hb_fail_count) = 0;
|
|
break;
|
|
default:
|
|
$var(n5_hb_fail_count) = $var(n5_hb_fail_count) + 1;
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
|
|
# Generate UUID for PCSCF
|
|
$var(pcscf_uuid) = $uuid(g);
|
|
|
|
# Register NF
|
|
$var(nf_reg_headers) = "content-type: application/json\r\n";
|
|
$var(nf_reg_headers) = $var(nf_reg_headers) + "accept: application/json,application/problem+json\r\n";
|
|
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n";
|
|
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-max-rsp-time: 10000\r\n";
|
|
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-discovery-service-names: nnrf-nfm\r\n";
|
|
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now);
|
|
|
|
$var(nf_reg_body) = '{
|
|
"nfInstanceId": "PCSCF_UUID",
|
|
"nfType": "AF",
|
|
"nfStatus": "REGISTERED",
|
|
"ipv4Addresses": ["N5_BIND_IP"],
|
|
"allowedNfTypes": ["SCP", "PCF"],
|
|
"priority": 0,
|
|
"capacity": 100,
|
|
"load": 0,
|
|
"nfServiceList": {
|
|
"PCSCF_UUID": {
|
|
"serviceInstanceId": "PCSCF_UUID",
|
|
"serviceName": "npcf-policyauthorization",
|
|
"versions": [
|
|
{
|
|
"apiVersionInUri": "v2",
|
|
"apiFullVersion": "2.0.0"
|
|
}
|
|
],
|
|
"scheme": "http",
|
|
"nfServiceStatus": "REGISTERED",
|
|
"ipEndPoints": [
|
|
{
|
|
"ipv4Address": "N5_BIND_IP",
|
|
"port": N5_BIND_PORT
|
|
}
|
|
],
|
|
"allowedNfTypes": [
|
|
"PCF"
|
|
],
|
|
"priority": 0,
|
|
"capacity": 100,
|
|
"load": 0
|
|
}
|
|
},
|
|
"nfProfileChangesSupportInd": true
|
|
}';
|
|
$var(nf_reg_body) = $(var(nf_reg_body){re.subst,/PCSCF_UUID/$var(pcscf_uuid)/g});
|
|
jansson_append("obj", "", "$var(nf_reg_body)", "$var(nf_reg_json_body)");
|
|
|
|
http_client_request_v2pk("PUT", "http://SCP_BIND_IP:SCP_BIND_PORT/nnrf-nfm/v1/nf-instances/$var(pcscf_uuid)", "$var(nf_reg_json_body)", "$var(nf_reg_headers)", "$var(nf_reg_result)");
|
|
switch ($rc) {
|
|
case 201:
|
|
xlog("L_INFO", "P-CSCF NF registered successfully at SCP\n");
|
|
$var(n5_initalized) = 1;
|
|
$var(n5_hb_fail_count) = 0;
|
|
route(NRF_NFM_SUBSCRIBE_PCF);
|
|
break;
|
|
default:
|
|
xlog("L_ERR", "P-CSCF NF failed to register at SCP with code=$rc\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
route[NRF_NFM_SUBSCRIBE_PCF] {
|
|
# Subscribe to PCF NF registration notification
|
|
$var(time_now) = $_s($timef(%a, %d %b %Y %H:%M:%S %Z));
|
|
$var(pcf_subc_headers) = "content-type: application/json\r\n";
|
|
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "accept: application/json,application/problem+json\r\n";
|
|
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n";
|
|
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-callback: Nnrf_NFManagement_NFStatusNotify\r\n";
|
|
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-max-rsp-time: 10000\r\n";
|
|
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-discovery-service-names: nnrf-nfm\r\n";
|
|
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now);
|
|
|
|
$var(pcf_subc_body) = '{
|
|
"nfStatusNotificationUri": "http://N5_BIND_IP:N5_BIND_PORT/nnrf-nfm/v1/nf-status-notify",
|
|
"reqNfInstanceId": "PCSCF_UUID",
|
|
"subscrCond": {
|
|
"nfType": "PCF"
|
|
},
|
|
"reqNfType": "AF",
|
|
"requesterFeatures": "1"
|
|
}';
|
|
$var(pcf_subc_body) = $(var(pcf_subc_body){re.subst,/PCSCF_UUID/$var(pcscf_uuid)/g});
|
|
jansson_append("obj", "", "$var(pcf_subc_body)", "$var(pcf_subc_json_body)");
|
|
|
|
http_client_request_v2pk("POST", "http://SCP_BIND_IP:SCP_BIND_PORT/nnrf-nfm/v1/subscriptions", "$var(pcf_subc_json_body)", "$var(pcf_subc_headers)", "$var(pcf_subc_result)");
|
|
switch ($rc) {
|
|
case 201:
|
|
xlog("L_INFO", "P-CSCF NF subscribed for PCF NF registration notification\n");
|
|
break;
|
|
default:
|
|
xlog("L_ERR", "P-CSCF NF failed to subscribe for PCF NF registration notification\n");
|
|
return;
|
|
}
|
|
}
|
|
#!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"
|