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