etc/kamailio.cfg
ee1d8334
 #!KAMAILIO
4b8ad64a
 #
954f25c2
 # Kamailio (OpenSER) SIP Server v5.4 - default configuration script
2e6b9322
 #     - web: https://www.kamailio.org
 #     - git: https://github.com/kamailio/kamailio
de69aa6e
 #
a2fe77bc
 # Direct your questions about this file to: <sr-users@lists.kamailio.org>
2ec46fbb
 #
2e6b9322
 # Refer to the Core CookBook at https://www.kamailio.org/wiki/
1af1c668
 # for an explanation of possible statements, functions and parameters.
 #
a0859762
 # Note: the comments can be:
 #     - lines starting with #, but not the pre-processor directives,
 #       which start with #!, like #!define, #!ifdef, #!endif, #!else, #!trydef,
 #       #!subst, #!substdef, ...
 #     - lines starting with //
 #     - blocks enclosed in between /* */
aebae41b
 # Note: the config performs symmetric SIP signaling
 #     - it sends the reply to the source address of the request
 #     - remove the use of force_rport() for asymmetric SIP signaling
a0859762
 #
41847d21
 # Several features can be enabled using '#!define WITH_FEATURE' directives:
1af1c668
 #
8eb9f927
 # *** To run in debug mode:
41847d21
 #     - define WITH_DEBUG
aebae41b
 #     - debug level increased to 3, logs still sent to syslog
 #     - debugger module loaded with cfgtrace endabled
1af1c668
 #
8eb9f927
 # *** To enable mysql:
41847d21
 #     - define WITH_MYSQL
 #
 # *** To enable authentication execute:
1af1c668
 #     - enable mysql
41847d21
 #     - define WITH_AUTH
aebae41b
 #     - add users using 'kamctl' or 'kamcli'
1af1c668
 #
7fae7a58
 # *** To enable IP authentication execute:
 #     - enable mysql
 #     - enable authentication
 #     - define WITH_IPAUTH
 #     - add IP addresses with group id '1' to 'address' table
 #
41847d21
 # *** To enable persistent user location execute:
1af1c668
 #     - enable mysql
41847d21
 #     - define WITH_USRLOCDB
1af1c668
 #
41847d21
 # *** To enable presence server execute:
1af1c668
 #     - enable mysql
41847d21
 #     - define WITH_PRESENCE
aebae41b
 #     - if modified headers or body in config must be used by presence handling:
 #     - define WITH_MSGREBUILD
1af1c668
 #
41847d21
 # *** To enable nat traversal execute:
 #     - define WITH_NAT
fcf895d2
 #     - option for NAT SIP OPTIONS keepalives: WITH_NATSIPPING
1af1c668
 #     - install RTPProxy: http://www.rtpproxy.org
 #     - start RTPProxy:
 #        rtpproxy -l _your_public_ip_ -s udp:localhost:7722
fcf895d2
 #
 # *** To use RTPEngine (instead of RTPProxy) for nat traversal execute:
 #     - define WITH_RTPENGINE
 #     - install RTPEngine: https://github.com/sipwise/rtpengine
 #     - start RTPEngine:
 #        rtpengine --listen-ng=127.0.0.1:2223 ...
1af1c668
 #
91790401
 # *** To enable PSTN gateway routing execute:
 #     - define WITH_PSTN
 #     - set the value of pstn.gw_ip
 #     - check route[PSTN] for regexp routing condition
 #
2d9a8454
 # *** To enable database aliases lookup execute:
 #     - enable mysql
 #     - define WITH_ALIASDB
 #
7b5d3d76
 # *** To enable speed dial lookup execute:
 #     - enable mysql
 #     - define WITH_SPEEDDIAL
 #
0eef0a5e
 # *** To enable multi-domain support execute:
 #     - enable mysql
 #     - define WITH_MULTIDOMAIN
 #
b7f00e7b
 # *** To enable TLS support execute:
 #     - adjust CFGDIR/tls.cfg as needed
 #     - define WITH_TLS
 #
9b97d01e
 # *** To enable JSONRPC over HTTP(S) support execute:
 #     - define WITH_JSONRPC
67d02a3b
 #     - adjust event_route[xhttp:request] for access policy
0b5ccf31
 #
f77093de
 # *** 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
 #
023381eb
 # *** To block 3XX redirect replies execute:
 #     - define WITH_BLOCK3XX
 #
a0859762
 # *** To block 401 and 407 authentication replies execute:
 #     - define WITH_BLOCK401407
 #
023381eb
 # *** To enable VoiceMail routing execute:
 #     - define WITH_VOICEMAIL
 #     - set the value of voicemail.srv_ip
 #     - adjust the value of voicemail.srv_port
 #
1af1c668
 # *** To enhance accounting execute:
 #     - enable mysql
41847d21
 #     - define WITH_ACCDB
ad87f9b3
 #     - add following columns to database
41847d21
 #!ifdef ACCDB_COMMENT
   ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
5b208d94
   ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';
41847d21
   ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
   ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
5b208d94
   ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';
41847d21
   ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
7a1e96b6
   ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
41847d21
   ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
 #!endif
4b8ad64a
 
7982d66c
 ####### Include Local Config If Exists #########
 import_file "kamailio-local.cfg"
 
aa60ed0d
 ####### Defined Values #########
 
ecd3a8ba
 # *** Value defines - IDs used later in config
aebae41b
 #!ifdef WITH_DEBUG
 #!define DBGLEVEL 3
 #!else
 #!define DBGLEVEL 2
 #!endif
 
ecd3a8ba
 #!ifdef WITH_MYSQL
 # - database URL - used to connect to database server by modules such
 #       as: auth_db, acc, usrloc, a.s.o.
aebae41b
 #!trydef DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"
72720355
 #!endif
aebae41b
 
0eef0a5e
 #!ifdef WITH_MULTIDOMAIN
 # - the value for 'use_domain' parameters
 #!define MULTIDOMAIN 1
 #!else
 #!define MULTIDOMAIN 0
 #!endif
2ec46fbb
 
aa60ed0d
 # - flags
 #   FLT_ - per transaction (message) flags
 #	FLB_ - per branch flags
 #!define FLT_ACC 1
 #!define FLT_ACCMISSED 2
 #!define FLT_ACCFAILED 3
 #!define FLT_NATS 5
 
 #!define FLB_NATB 6
 #!define FLB_NATSIPPING 7
 
2ec46fbb
 ####### Global Parameters #########
4b8ad64a
 
aebae41b
 /* LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR, ... */
 debug=DBGLEVEL
 
 /* set to 'yes' to print log messages to terminal or use '-E' cli option */
41847d21
 log_stderror=no
 
10a05af7
 memdbg=5
 memlog=5
41847d21
 
2ec46fbb
 log_facility=LOG_LOCAL0
387e2a80
 log_prefix="{$mt $hdr(CSeq) $ci} "
4b8ad64a
 
409cb202
 /* number of SIP routing processes for each UDP socket
  * - value inherited by tcp_children and sctp_children when not set explicitely */
8eb9f927
 children=8
42ee1c91
 
2ec46fbb
 /* uncomment the next line to disable TCP (default on) */
a0859762
 # disable_tcp=yes
2ec46fbb
 
409cb202
 /* number of SIP routing processes for all TCP/TLS sockets */
 # tcp_children=8
 
2ec46fbb
 /* uncomment the next line to disable the auto discovery of local aliases
a0859762
  * based on reverse DNS on IPs (default on) */
 # auto_aliases=no
2ec46fbb
 
aebae41b
 /* add local domain aliases - it can be set many times */
387e2a80
 # alias="sip.mydomain.com"
7fae7a58
 
aebae41b
 /* listen sockets - if none set, Kamailio binds to all local IP addresses
  * - basic prototype (full prototype can be found in Wiki - Core Cookbook):
  *      listen=[proto]:[localip]:[lport] advertise [publicip]:[pport]
  * - it can be set many times to add more sockets to listen to */
a0859762
 # listen=udp:10.0.0.10:5060
2ec46fbb
 
a0859762
 /* life time of TCP connection when there is no traffic
  * - a bit higher than registration expires to cope with UA behind NAT */
195ab47e
 tcp_connection_lifetime=3605
 
409cb202
 /* upper limit for TCP connections (it includes the TLS connections) */
 tcp_max_connections=2048
 
41bdb340
 #!ifdef WITH_JSONRPC
 tcp_accept_no_cl=yes
 #!endif
 
409cb202
 #!ifdef WITH_TLS
 enable_tls=yes
 
 /* upper limit for TLS connections */
 tls_max_connections=2048
 #!endif
 
41bdb340
 /* set it to yes to enable sctp and load sctp.so module */
33afceac
 enable_sctp=no
9b97d01e
 
91790401
 ####### Custom Parameters #########
 
a0859762
 /* These parameters can be modified runtime via RPC interface
  * - see the documentation of 'cfg_rpc' module.
  *
  * Format: group.id = value 'desc' description
  * Access: $sel(cfg_get.group.id) or @cfg_get.group.id */
91790401
 
 #!ifdef WITH_PSTN
a0859762
 /* PSTN GW Routing
  *
  * - pstn.gw_ip: valid IP or hostname as string value, example:
  * pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"
  *
  * - by default is empty to avoid misrouting */
91790401
 pstn.gw_ip = "" desc "PSTN GW Address"
4ef83985
 pstn.gw_port = "" desc "PSTN GW Port"
91790401
 #!endif
 
023381eb
 #!ifdef WITH_VOICEMAIL
a0859762
 /* VoiceMail Routing on offline, busy or no answer
  *
  * - by default Voicemail server IP is empty to avoid misrouting */
023381eb
 voicemail.srv_ip = "" desc "VoiceMail IP Address"
 voicemail.srv_port = "5060" desc "VoiceMail Port"
 #!endif
91790401
 
2ec46fbb
 ####### Modules Section ########
4b8ad64a
 
a0859762
 /* set paths to location of modules */
 # mpath="/usr/local/lib/kamailio/modules/"
3649b57e
 
41847d21
 #!ifdef WITH_MYSQL
 loadmodule "db_mysql.so"
 #!endif
0eef0a5e
 
9b97d01e
 #!ifdef WITH_JSONRPC
 loadmodule "xhttp.so"
 #!endif
dc5a9e96
 loadmodule "jsonrpcs.so"
10a05af7
 loadmodule "kex.so"
3b09b31b
 loadmodule "corex.so"
3649b57e
 loadmodule "tm.so"
10a05af7
 loadmodule "tmx.so"
da701bcd
 loadmodule "sl.so"
3649b57e
 loadmodule "rr.so"
9a63b314
 loadmodule "pv.so"
3649b57e
 loadmodule "maxfwd.so"
 loadmodule "usrloc.so"
 loadmodule "registrar.so"
 loadmodule "textops.so"
aebae41b
 loadmodule "textopsx.so"
af41c841
 loadmodule "siputils.so"
2ec46fbb
 loadmodule "xlog.so"
350eb605
 loadmodule "sanity.so"
f8bf9633
 loadmodule "ctl.so"
751114fd
 loadmodule "cfg_rpc.so"
2ec46fbb
 loadmodule "acc.so"
7d3d5ac3
 loadmodule "counters.so"
0eef0a5e
 
41847d21
 #!ifdef WITH_AUTH
 loadmodule "auth.so"
 loadmodule "auth_db.so"
7fae7a58
 #!ifdef WITH_IPAUTH
 loadmodule "permissions.so"
 #!endif
41847d21
 #!endif
2d9a8454
 
 #!ifdef WITH_ALIASDB
 loadmodule "alias_db.so"
 #!endif
 
7b5d3d76
 #!ifdef WITH_SPEEDDIAL
 loadmodule "speeddial.so"
 #!endif
 
0eef0a5e
 #!ifdef WITH_MULTIDOMAIN
 loadmodule "domain.so"
 #!endif
 
41847d21
 #!ifdef WITH_PRESENCE
 loadmodule "presence.so"
 loadmodule "presence_xml.so"
 #!endif
2ec46fbb
 
41847d21
 #!ifdef WITH_NAT
 loadmodule "nathelper.so"
96fedc52
 #!ifdef WITH_RTPENGINE
 loadmodule "rtpengine.so"
 #!else
1e72cd4c
 loadmodule "rtpproxy.so"
41847d21
 #!endif
96fedc52
 #!endif
4b8ad64a
 
b7f00e7b
 #!ifdef WITH_TLS
 loadmodule "tls.so"
 #!endif
 
f77093de
 #!ifdef WITH_ANTIFLOOD
 loadmodule "htable.so"
 loadmodule "pike.so"
 #!endif
 
66d0041e
 #!ifdef WITH_DEBUG
 loadmodule "debugger.so"
 #!endif
 
4b8ad64a
 # ----------------- setting module-specific parameters ---------------
 
f136276a
 
dc5a9e96
 # ----- jsonrpcs params -----
e280aab5
 modparam("jsonrpcs", "pretty_format", 1)
dc5a9e96
 /* set the path to RPC fifo control file */
e29dce78
 # modparam("jsonrpcs", "fifo_name", "/run/kamailio/kamailio_rpc.fifo")
dc5a9e96
 /* set the path to RPC unix socket control file */
e29dce78
 # modparam("jsonrpcs", "dgram_socket", "/run/kamailio/kamailio_rpc.sock")
9b97d01e
 #!ifdef WITH_JSONRPC
 modparam("jsonrpcs", "transport", 7)
 #!endif
f136276a
 
850320ca
 # ----- ctl params -----
a0859762
 /* set the path to RPC unix socket control file */
e29dce78
 # modparam("ctl", "binrpc", "unix:/run/kamailio/kamailio_ctl")
4b8ad64a
 
d9269f8d
 # ----- sanity params -----
 modparam("sanity", "autodrop", 0)
 
cba4663b
 # ----- tm params -----
 # auto-discard branches from previous serial forking leg
 modparam("tm", "failure_reply_mode", 3)
 # default retransmission timeout: 30sec
 modparam("tm", "fr_timer", 30000)
 # default invite retransmission timeout after 1xx: 120sec
 modparam("tm", "fr_inv_timer", 120000)
 
2ec46fbb
 # ----- rr params -----
c90369b4
 # set next param to 1 to add value to ;lr param (helps with some UAs)
 modparam("rr", "enable_full_lr", 0)
2ec46fbb
 # do not append from tag to the RR (no need for this script)
 modparam("rr", "append_fromtag", 0)
 
0eef0a5e
 # ----- registrar params -----
2ec46fbb
 modparam("registrar", "method_filtering", 1)
 /* uncomment the next line to disable parallel forking via location */
 # modparam("registrar", "append_branches", 0)
 /* uncomment the next line not to allow more than 10 contacts per AOR */
a0859762
 # modparam("registrar", "max_contacts", 10)
 /* max value for expires of registrations */
195ab47e
 modparam("registrar", "max_expires", 3600)
a0859762
 /* set it to 1 to enable GRUU */
f55f4dcd
 modparam("registrar", "gruu_enabled", 0)
aebae41b
 /* set it to 0 to disable Path handling */
 modparam("registrar", "use_path", 1)
 /* save Path even if not listed in Supported header */
 modparam("registrar", "path_mode", 0)
2ec46fbb
 
 # ----- acc params -----
0eef0a5e
 /* what special events should be accounted ? */
 modparam("acc", "early_media", 0)
 modparam("acc", "report_ack", 0)
 modparam("acc", "report_cancels", 0)
2ec46fbb
 /* by default ww do not adjust the direct of the sequential requests.
a0859762
  * if you enable this parameter, be sure the enable "append_fromtag"
  * in "rr" module */
2ec46fbb
 modparam("acc", "detect_direction", 0)
 /* account triggers (flags) */
aa60ed0d
 modparam("acc", "log_flag", FLT_ACC)
 modparam("acc", "log_missed_flag", FLT_ACCMISSED)
8eb9f927
 modparam("acc", "log_extra",
5b208d94
 	"src_user=$fU;src_domain=$fd;src_ip=$si;"
 	"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
aa60ed0d
 modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
41847d21
 /* enhanced DB accounting */
 #!ifdef WITH_ACCDB
aa60ed0d
 modparam("acc", "db_flag", FLT_ACC)
 modparam("acc", "db_missed_flag", FLT_ACCMISSED)
ecd3a8ba
 modparam("acc", "db_url", DBURL)
41847d21
 modparam("acc", "db_extra",
5b208d94
 	"src_user=$fU;src_domain=$fd;src_ip=$si;"
 	"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
41847d21
 #!endif
2ec46fbb
 
 # ----- usrloc params -----
aebae41b
 modparam("usrloc", "timer_interval", 60)
 modparam("usrloc", "timer_procs", 1)
 modparam("usrloc", "use_domain", MULTIDOMAIN)
41847d21
 /* enable DB persistency for location entries */
 #!ifdef WITH_USRLOCDB
ecd3a8ba
 modparam("usrloc", "db_url", DBURL)
0eef0a5e
 modparam("usrloc", "db_mode", 2)
41847d21
 #!endif
4b8ad64a
 
2ec46fbb
 # ----- auth_db params -----
41847d21
 #!ifdef WITH_AUTH
0eef0a5e
 modparam("auth_db", "db_url", DBURL)
41847d21
 modparam("auth_db", "calculate_ha1", yes)
 modparam("auth_db", "password_column", "password")
 modparam("auth_db", "load_credentials", "")
0eef0a5e
 modparam("auth_db", "use_domain", MULTIDOMAIN)
7fae7a58
 
0eef0a5e
 # ----- permissions params -----
7fae7a58
 #!ifdef WITH_IPAUTH
ecd3a8ba
 modparam("permissions", "db_url", DBURL)
66c25bdd
 modparam("permissions", "load_backends", 1)
7fae7a58
 #!endif
 
41847d21
 #!endif
2ec46fbb
 
 # ----- alias_db params -----
2d9a8454
 #!ifdef WITH_ALIASDB
 modparam("alias_db", "db_url", DBURL)
0eef0a5e
 modparam("alias_db", "use_domain", MULTIDOMAIN)
2d9a8454
 #!endif
2ec46fbb
 
0fd954bc
 # ----- speeddial params -----
7b5d3d76
 #!ifdef WITH_SPEEDDIAL
 modparam("speeddial", "db_url", DBURL)
 modparam("speeddial", "use_domain", MULTIDOMAIN)
 #!endif
 
0eef0a5e
 # ----- domain params -----
 #!ifdef WITH_MULTIDOMAIN
 modparam("domain", "db_url", DBURL)
a0859762
 /* register callback to match myself condition with domains list */
0eef0a5e
 modparam("domain", "register_myself", 1)
 #!endif
2ec46fbb
 
41847d21
 #!ifdef WITH_PRESENCE
0eef0a5e
 # ----- presence params -----
 modparam("presence", "db_url", DBURL)
 
 # ----- presence_xml params -----
 modparam("presence_xml", "db_url", DBURL)
41847d21
 modparam("presence_xml", "force_active", 1)
 #!endif
 
 #!ifdef WITH_NAT
fcf895d2
 #!ifdef WITH_RTPENGINE
 # ----- rtpengine params -----
 modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:2223")
 #!else
0eef0a5e
 # ----- rtpproxy params -----
1e72cd4c
 modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722")
d960c2fe
 #!endif
0eef0a5e
 # ----- nathelper params -----
41847d21
 modparam("nathelper", "natping_interval", 30)
 modparam("nathelper", "ping_nated_only", 1)
aa60ed0d
 modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
41847d21
 modparam("nathelper", "sipping_from", "sip:pinger@kamailio.org")
aa60ed0d
 
 # params needed for NAT traversal in other modules
0eef0a5e
 modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
aa60ed0d
 modparam("usrloc", "nat_bflag", FLB_NATB)
41847d21
 #!endif
4b8ad64a
 
b7f00e7b
 #!ifdef WITH_TLS
 # ----- tls params -----
 modparam("tls", "config", "/usr/local/etc/kamailio/tls.cfg")
 #!endif
 
f77093de
 #!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 -----
a0859762
 /* ip ban htable with autoexpire after 5 minutes */
f77093de
 modparam("htable", "htable", "ipban=>size=8;autoexpire=300;")
 #!endif
b7f00e7b
 
66d0041e
 #!ifdef WITH_DEBUG
 # ----- debugger params -----
 modparam("debugger", "cfgtrace", 1)
c3f57334
 modparam("debugger", "log_level_name", "exec")
66d0041e
 #!endif
 
2ec46fbb
 ####### Routing Logic ########
4b8ad64a
 
2ec46fbb
 
a0859762
 /* Main SIP request routing logic
  * - processing of any incoming SIP request starts with this route
  * - note: this is the same as route { ... } */
751114fd
 request_route {
7fae7a58
 
 	# per request initial checks
 	route(REQINIT);
 
 	# NAT detection
cf598f32
 	route(NATDETECT);
7fae7a58
 
 	# CANCEL processing
be1ed10d
 	if (is_method("CANCEL")) {
ef63f7cd
 		if (t_check_trans()) {
 			route(RELAY);
 		}
7fae7a58
 		exit;
 	}
 
868f9996
 	# handle retransmissions
 	if (!is_method("ACK")) {
 		if(t_precheck_trans()) {
 			t_check_trans();
 			exit;
 		}
 		t_check_trans();
 	}
 
8a7a06f4
 	# handle requests within SIP dialogs
 	route(WITHINDLG);
 
 	### only initial requests (no To tag)
 
7fae7a58
 	# authentication
 	route(AUTH);
 
 	# record routing for dialog forming requests (in case they are routed)
 	# - remove preloaded route headers
 	remove_hf("Route");
3db2f281
 	if (is_method("INVITE|SUBSCRIBE")) {
7fae7a58
 		record_route();
3db2f281
 	}
7fae7a58
 
 	# account only INVITEs
be1ed10d
 	if (is_method("INVITE")) {
aa60ed0d
 		setflag(FLT_ACC); # do accounting
7fae7a58
 	}
 
 	# dispatch requests to foreign domains
 	route(SIPOUT);
 
 	### requests for my local domains
 
 	# handle presence related requests
 	route(PRESENCE);
 
 	# handle registrations
 	route(REGISTRAR);
4b8ad64a
 
be1ed10d
 	if ($rU==$null) {
7fae7a58
 		# request with no Username in RURI
 		sl_send_reply("484","Address Incomplete");
 		exit;
 	}
 
 	# dispatch destinations to PSTN
 	route(PSTN);
 
 	# user location service
 	route(LOCATION);
 }
 
be1ed10d
 # Wrapper for relaying requests
7fae7a58
 route[RELAY] {
 
cf598f32
 	# enable additional event routes for forwarded requests
 	# - serial forking, RTP relaying handling, a.s.o.
c7603525
 	if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
 		if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
 	}
 	if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
 		if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
cf598f32
 	}
7fae7a58
 	if (is_method("INVITE")) {
c7603525
 		if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
7fae7a58
 	}
 
 	if (!t_relay()) {
 		sl_reply_error();
 	}
 	exit;
 }
 
 # Per SIP request initial checks
 route[REQINIT] {
3036a53f
 	# no connect for sending replies
 	set_reply_no_connect();
aebae41b
 	# enforce symmetric signaling
 	# - send back replies to the source address of request
 	force_rport();
3036a53f
 
f77093de
 #!ifdef WITH_ANTIFLOOD
49420bac
 	# flood detection from same IP and traffic ban for a while
f77093de
 	# be sure you exclude checking trusted peers, such as pstn gateways
 	# - local host excluded (e.g., loop to self)
895ae33c
 	if(src_ip!=myself) {
 		if($sht(ipban=>$si)!=$null) {
f77093de
 			# ip is already blocked
 			xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
 			exit;
 		}
895ae33c
 		if (!pike_check_req()) {
f77093de
 			xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
 			$sht(ipban=>$si) = 1;
 			exit;
 		}
 	}
1948fa53
 #!endif
07dbb965
 	if($ua =~ "friendly-scanner|sipcli|sipvicious|VaxSIPUserAgent") {
8eb9f927
 		# silent drop for scanners - uncomment next line if want to reply
 		# sl_send_reply("200", "OK");
ef86e60e
 		exit;
 	}
f77093de
 
4b8ad64a
 	if (!mf_process_maxfwd_header("10")) {
 		sl_send_reply("483","Too Many Hops");
155cb06f
 		exit;
2ec46fbb
 	}
 
895ae33c
 	if(is_method("OPTIONS") && uri==myself && $rU==$null) {
 		sl_send_reply("200","Keepalive");
 		exit;
 	}
 
c4ce16fc
 	if(!sanity_check("17895", "7")) {
d9269f8d
 		xlog("Malformed SIP request from $si:$sp\n");
350eb605
 		exit;
 	}
7fae7a58
 }
350eb605
 
7fae7a58
 # Handle requests within SIP dialogs
 route[WITHINDLG] {
be1ed10d
 	if (!has_totag()) return;
 
 	# sequential request withing a dialog should
 	# take the path determined by record-routing
 	if (loose_route()) {
 		route(DLGURI);
 		if (is_method("BYE")) {
 			setflag(FLT_ACC); # do accounting ...
 			setflag(FLT_ACCFAILED); # ... even if the transaction fails
3db2f281
 		} else if ( is_method("ACK") ) {
16bfd2de
 			# ACK is forwarded statelessly
be1ed10d
 			route(NATMANAGE);
3db2f281
 		} else if ( is_method("NOTIFY") ) {
be1ed10d
 			# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
 			record_route();
 		}
 		route(RELAY);
 		exit;
 	}
 
 	if (is_method("SUBSCRIBE") && uri == myself) {
 		# in-dialog subscribe requests
 		route(PRESENCE);
 		exit;
 	}
 	if ( is_method("ACK") ) {
 		if ( t_check_trans() ) {
 			# no loose-route, but stateful ACK;
 			# must be an ACK after a 487
 			# or e.g. 404 from upstream server
074f6a3e
 			route(RELAY);
be1ed10d
 			exit;
2ec46fbb
 		} else {
be1ed10d
 			# ACK without matching transaction ... ignore and discard
 			exit;
2ec46fbb
 		}
 	}
be1ed10d
 	sl_send_reply("404","Not here");
 	exit;
7fae7a58
 }
155cb06f
 
7fae7a58
 # Handle SIP registrations
 route[REGISTRAR] {
be1ed10d
 	if (!is_method("REGISTER")) return;
4b8ad64a
 
be1ed10d
 	if(isflagset(FLT_NATS)) {
 		setbflag(FLB_NATB);
 #!ifdef WITH_NATSIPPING
 		# do SIP NAT pinging
 		setbflag(FLB_NATSIPPING);
 #!endif
2ec46fbb
 	}
3db2f281
 	if (!save("location")) {
be1ed10d
 		sl_reply_error();
3db2f281
 	}
be1ed10d
 	exit;
7fae7a58
 }
4b8ad64a
 
be1ed10d
 # User location service
7fae7a58
 route[LOCATION] {
2d9a8454
 
0fd954bc
 #!ifdef WITH_SPEEDDIAL
7b5d3d76
 	# search for short dialing - 2-digit extension
3db2f281
 	if($rU=~"^[0-9][0-9]$") {
 		if(sd_lookup("speed_dial")) {
195ab47e
 			route(SIPOUT);
3db2f281
 		}
 	}
7b5d3d76
 #!endif
 
2d9a8454
 #!ifdef WITH_ALIASDB
 	# search in DB-based aliases
3db2f281
 	if(alias_db_lookup("dbaliases")) {
195ab47e
 		route(SIPOUT);
3db2f281
 	}
2d9a8454
 #!endif
2ec46fbb
 
023381eb
 	$avp(oexten) = $rU;
2ec46fbb
 	if (!lookup("location")) {
023381eb
 		$var(rc) = $rc;
 		route(TOVOICEMAIL);
 		t_newtran();
 		switch ($var(rc)) {
2ec46fbb
 			case -1:
 			case -3:
023381eb
 				send_reply("404", "Not Found");
2ec46fbb
 				exit;
 			case -2:
023381eb
 				send_reply("405", "Method Not Allowed");
2ec46fbb
 				exit;
 		}
 	}
 
 	# when routing via usrloc, log the missed calls also
be1ed10d
 	if (is_method("INVITE")) {
aa60ed0d
 		setflag(FLT_ACCMISSED);
1af1c668
 	}
ef63f7cd
 
 	route(RELAY);
 	exit;
4b8ad64a
 }
 
be1ed10d
 # Presence server processing
7fae7a58
 route[PRESENCE] {
3db2f281
 	if(!is_method("PUBLISH|SUBSCRIBE")) return;
7fae7a58
 
e7da9f72
 	if(is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
 		route(TOVOICEMAIL);
 		# returns here if no voicemail server is configured
 		sl_send_reply("404", "No voicemail service");
 		exit;
 	}
 
41847d21
 #!ifdef WITH_PRESENCE
aebae41b
 #!ifdef WITH_MSGREBUILD
 	# apply changes in case the request headers or body were modified
 	msg_apply_changes();
 #!endif
be1ed10d
 	if (!t_newtran()) {
41847d21
 		sl_reply_error();
 		exit;
e7da9f72
 	}
41847d21
 
be1ed10d
 	if(is_method("PUBLISH")) {
41847d21
 		handle_publish();
 		t_release();
e7da9f72
 	} else if(is_method("SUBSCRIBE")) {
41847d21
 		handle_subscribe();
 		t_release();
 	}
 	exit;
 #!endif
8eb9f927
 
1af1c668
 	# if presence enabled, this part will not be executed
be1ed10d
 	if (is_method("PUBLISH") || $rU==$null) {
1af1c668
 		sl_send_reply("404", "Not here");
 		exit;
 	}
 	return;
 }
 
49420bac
 # IP authorization and user authentication
18ec6f5d
 route[AUTH] {
41847d21
 #!ifdef WITH_AUTH
7fae7a58
 
 #!ifdef WITH_IPAUTH
be1ed10d
 	if((!is_method("REGISTER")) && allow_source_address()) {
66179540
 		# source IP allowed
 		return;
 	}
8d16577b
 #!endif
41847d21
 
3db2f281
 	if (is_method("REGISTER") || from_uri==myself) {
66179540
 		# authenticate requests
 		if (!auth_check("$fd", "subscriber", "1")) {
 			auth_challenge("$fd", "0");
 			exit;
41847d21
 		}
66179540
 		# user authenticated - remove auth header
 		if(!is_method("REGISTER|PUBLISH"))
 			consume_credentials();
41847d21
 	}
66179540
 	# if caller is not local subscriber, then check if it calls
 	# a local destination, otherwise deny, not an open relay here
be1ed10d
 	if (from_uri!=myself && uri!=myself) {
66179540
 		sl_send_reply("403","Not relaying");
 		exit;
 	}
 
41f41d6d
 #!else
 
 	# authentication not enabled - do not relay at all to foreign networks
 	if(uri!=myself) {
 		sl_send_reply("403","Not relaying");
 		exit;
 	}
 
41847d21
 #!endif
1af1c668
 	return;
2ec46fbb
 }
 
be1ed10d
 # Caller NAT detection
cf598f32
 route[NATDETECT] {
41847d21
 #!ifdef WITH_NAT
 	if (nat_uac_test("19")) {
cf598f32
 		if (is_method("REGISTER")) {
41847d21
 			fix_nated_register();
 		} else {
3db2f281
 			if(is_first_hop()) {
66ed11c9
 				set_contact_alias();
3db2f281
 			}
41847d21
 		}
aa60ed0d
 		setflag(FLT_NATS);
41847d21
 	}
 #!endif
1af1c668
 	return;
 }
 
49420bac
 # RTPProxy control and signaling updates for NAT traversal
cf598f32
 route[NATMANAGE] {
41847d21
 #!ifdef WITH_NAT
cf598f32
 	if (is_request()) {
 		if(has_totag()) {
 			if(check_route_param("nat=yes")) {
 				setbflag(FLB_NATB);
 			}
 		}
 	}
3db2f281
 	if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;
cf598f32
 
fcf895d2
 #!ifdef WITH_RTPENGINE
7c6ef434
 	if(nat_uac_test("8")) {
fcf895d2
 		rtpengine_manage("replace-origin replace-session-connection");
ac31eb11
 	} else {
fcf895d2
 		rtpengine_manage("trust-address replace-origin replace-session-connection");
7c6ef434
 	}
fcf895d2
 #!else
7c6ef434
 	if(nat_uac_test("8")) {
 		rtpproxy_manage("co");
 	} else {
ac31eb11
 		rtpproxy_manage("cor");
 	}
7c6ef434
 #!endif
cf598f32
 
 	if (is_request()) {
 		if (!has_totag()) {
0193489c
 			if(t_is_branch_route()) {
 				add_rr_param(";nat=yes");
 			}
cf598f32
 		}
 	}
 	if (is_reply()) {
 		if(isbflagset(FLB_NATB)) {
fe24ed17
 			if(is_first_hop())
66ed11c9
 				set_contact_alias();
cf598f32
 		}
41847d21
 	}
3036a53f
 
 	if(isbflagset(FLB_NATB)) {
8bba208f
 		# no connect message in a dialog involving NAT traversal
56bf76bb
 		if (is_request()) {
 			if(has_totag()) {
 				set_forward_no_connect();
 			}
 		}
3036a53f
 	}
41847d21
 #!endif
1af1c668
 	return;
 }
2ec46fbb
 
9d720b83
 # URI update for dialog requests
 route[DLGURI] {
 #!ifdef WITH_NAT
 	if(!isdsturiset()) {
 		handle_ruri_alias();
 	}
 #!endif
 	return;
 }
 
7fae7a58
 # Routing to foreign domains
 route[SIPOUT] {
be1ed10d
 	if (uri==myself) return;
 
aebae41b
 	append_hf("P-Hint: outbound\r\n");
be1ed10d
 	route(RELAY);
 	exit;
7fae7a58
 }
 
91790401
 # PSTN GW routing
 route[PSTN] {
 #!ifdef WITH_PSTN
 	# check if PSTN GW IP is defined
 	if (strempty($sel(cfg_get.pstn.gw_ip))) {
49420bac
 		xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");
91790401
 		return;
 	}
 
 	# route to PSTN dialed numbers starting with '+' or '00'
 	#     (international format)
 	# - update the condition to match your dialing rules for PSTN routing
3db2f281
 	if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$")) return;
91790401
 
 	# only local users allowed to call
 	if(from_uri!=myself) {
 		sl_send_reply("403", "Not Allowed");
 		exit;
 	}
 
b4ad3105
 	# normalize target number for pstn gateway
 	# - convert leading 00 to +
 	if (starts_with("$rU", "00")) {
 		strip(2);
 		prefix("+");
 	}
 
4ef83985
 	if (strempty($sel(cfg_get.pstn.gw_port))) {
 		$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
 	} else {
 		$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":"
 					+ $sel(cfg_get.pstn.gw_port);
 	}
91790401
 
 	route(RELAY);
 	exit;
 #!endif
 
 	return;
 }
 
9b97d01e
 # JSONRPC over HTTP(S) routing
 #!ifdef WITH_JSONRPC
 event_route[xhttp:request] {
 	set_reply_close();
 	set_reply_no_connect();
 	if(src_ip!=127.0.0.1) {
 		xhttp_reply("403", "Forbidden", "text/html",
 				"<html><body>Not allowed from $si</body></html>");
0b5ccf31
 		exit;
 	}
9b97d01e
 	if ($hu =~ "^/RPC") {
 		jsonrpc_dispatch();
 		exit;
 	}
 
 	xhttp_reply("200", "OK", "text/html",
 				"<html><body>Wrong URL $hu</body></html>");
     exit;
0b5ccf31
 }
 #!endif
 
be1ed10d
 # Routing to voicemail server
023381eb
 route[TOVOICEMAIL] {
 #!ifdef WITH_VOICEMAIL
3db2f281
 	if(!is_method("INVITE|SUBSCRIBE")) return;
023381eb
 
 	# check if VoiceMail server IP is defined
 	if (strempty($sel(cfg_get.voicemail.srv_ip))) {
aef62d82
 		xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n");
023381eb
 		return;
 	}
e7da9f72
 	if(is_method("INVITE")) {
3db2f281
 		if($avp(oexten)==$null) return;
 
e7da9f72
 		$ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)
0e3f1ff9
 				+ ":" + $sel(cfg_get.voicemail.srv_port);
e7da9f72
 	} else {
3db2f281
 		if($rU==$null) return;
 
e7da9f72
 		$ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip)
 				+ ":" + $sel(cfg_get.voicemail.srv_port);
 	}
023381eb
 	route(RELAY);
 	exit;
 #!endif
 
 	return;
 }
 
be1ed10d
 # Manage outgoing branches
cf598f32
 branch_route[MANAGE_BRANCH] {
 	xdbg("new branch [$T_branch_idx] to $ru\n");
 	route(NATMANAGE);
1af1c668
 }
 
be1ed10d
 # Manage incoming replies
d9269f8d
 reply_route {
 	if(!sanity_check("17604", "6")) {
 		xlog("Malformed SIP response from $si:$sp\n");
 		drop;
 	}
 }
 
 # Manage incoming replies in transaction context
cf598f32
 onreply_route[MANAGE_REPLY] {
1af1c668
 	xdbg("incoming reply\n");
3db2f281
 	if(status=~"[12][0-9][0-9]") {
cf598f32
 		route(NATMANAGE);
3db2f281
 	}
2ec46fbb
 }
 
be1ed10d
 # Manage failure routing cases
cf598f32
 failure_route[MANAGE_FAILURE] {
 	route(NATMANAGE);
1af1c668
 
3db2f281
 	if (t_is_canceled()) exit;
2ec46fbb
 
023381eb
 #!ifdef WITH_BLOCK3XX
 	# block call redirect based on 3xx replies.
 	if (t_check_status("3[0-9][0-9]")) {
 		t_reply("404","Not found");
 		exit;
 	}
 #!endif
 
a0859762
 #!ifdef WITH_BLOCK401407
 	# block call redirect based on 401, 407 replies.
 	if (t_check_status("401|407")) {
 		t_reply("404","Not found");
 		exit;
 	}
 #!endif
 
023381eb
 #!ifdef WITH_VOICEMAIL
 	# serial forking
 	# - route to voicemail on busy or no answer (timeout)
 	if (t_check_status("486|408")) {
c4b29f6f
 		$du = $null;
023381eb
 		route(TOVOICEMAIL);
 		exit;
 	}
 #!endif
2ec46fbb
 }