#!KAMAILIO # # Kamailio SBC Configuration # Emtex 07-2020 # # # Simple routing of all inbound calls to all configured application servers # application servers configured in mysql database # # # Configuration #!define DBURL "mysql://kamailio:xxxxxxxxxxxx@localhost/kamailio" # !define WITH_DEBUG mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules" #!define INTERNAL_IP 192.168.10.180 #!define EXTERNAL_IP 88.198.223.80 # # Program Config # #!ifdef WITH_DEBUG debug=4 log_stderror=yes #!else debug=2 log_stderror=no #!endif memdbg=5 memlog=5 log_facility=LOG_LOCAL0 fork=yes children=4 # we want UDP only disable_tcp=yes # no aliases ?! auto_aliases=no # local domains alias="88.198.223.80" port=5060 listen=udp:EXTERNAL_IP:5060 listen=udp:INTERNAL_IP:5060 sip_warning=no loadmodule "db_mysql.so" # loadmodule "mi_fifo.so" loadmodule "kex.so" loadmodule "tm.so" loadmodule "tmx.so" loadmodule "sl.so" loadmodule "rr.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "siputils.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "ctl.so" #loadmodule "mi_rpc.so" loadmodule "acc.so" loadmodule "dispatcher.so" loadmodule "jsonrpcs.so" loadmodule "sqlops.so" # # Module specific Parameters # # ----- mi_fifo params ----- # modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo") # ----- 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", 0) # ----- acc params ----- modparam("acc", "log_flag", 1) modparam("acc", "failed_transaction_flag", 3) modparam("acc", "log_extra", "src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si") # ----- tm params ----- modparam("tm", "fr_timer", 2000) modparam("tm", "fr_inv_timer", 40000) # ----- dispatcher params ----- modparam("dispatcher", "db_url", DBURL) modparam("dispatcher", "table_name", "dispatcher") modparam("dispatcher", "flags", 2) #modparam("dispatcher", "dst_avp", "$avp(AVP_DST)") #modparam("dispatcher", "grp_avp", "$avp(AVP_GRP)") #modparam("dispatcher", "cnt_avp", "$avp(AVP_CNT)") modparam("dispatcher", "ds_ping_from", "sip:sbc@primary.sip.intra.emtex.net") modparam("dispatcher", "ds_ping_interval", 5) # default: 0 #modparam("dispatcher", "ds_probing_threshold", 10) # default: 1 modparam("dispatcher", "ds_inactive_threshold", 6) # default: 1 modparam("dispatcher", "ds_probing_mode", 1) # default: 0 modparam("dispatcher", "ds_ping_latency_stats", 1) # default: 0 modparam("sqlops","sqlcon","altdb =>mysql://kamailio:xxxxxxxxxxxx@192.168.10.68/MASTER") # # Call Routing # # main request routing logic route { # per request initial checks route(REQINIT); # handle requests within SIP dialogs route(WITHINDLG); ### only initial requests (no To tag) # CANCEL processing if (is_method("CANCEL")) { if (t_check_trans()) t_relay(); exit; } t_check_trans(); # record routing for dialog forming requests (in case they are routed) # - remove preloaded route headers remove_hf("Route"); if (is_method("INVITE|SUBSCRIBE")) record_route(); # account only INVITEs if (is_method("INVITE")) { setflag(1); # do accounting } # handle presence related requests route(PRESENCE); # handle registrations route(REGISTRAR); if (uri==myself) { if ((method==OPTIONS) && (! uri=~"sip:.*[@]+.*")) { options_reply(); } } if ($rU==$null) { # request with no Username in RURI sl_send_reply("484","Address Incomplete"); exit; } # Route Outbound route(SIPOUT); # dispatch destinations route(DISPATCH); route(RELAY); } route[RELAY] { if (!t_relay()) { sl_reply_error(); } exit; } # Per SIP request initial checks route[REQINIT] { 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; } } # Handle requests within SIP dialogs route[WITHINDLG] { if (has_totag()) { # sequential request withing a dialog should # take the path determined by record-routing if (loose_route()) { if (is_method("BYE")) { setflag(1); # do accounting ... setflag(3); # ... even if the transaction fails } route(RELAY); } else { if (is_method("SUBSCRIBE") && uri == myself) { # in-dialog subscribe requests route(PRESENCE); exit; } if ( is_method("ACK") ) { if ( t_check_trans() ) { # non loose-route, but stateful ACK; # must be 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; } } # Handle SIP registrations route[REGISTRAR] { if(!is_method("REGISTER")) return; sl_send_reply("404", "No registrar"); t_relay(); exit; } # Presence server route route[PRESENCE] { if(!is_method("PUBLISH|SUBSCRIBE")) return; sl_send_reply("404", "Not here"); exit; } # Route Outbound Calls route[SIPOUT] { if (uri==myself) return; # only allow outbound routing if packet comes over our internal ip if ($Ri!=$def(INTERNAL_IP)) { send_reply("403", "you shall not pass!"); exit; } append_hf("P-hint: outbound\r\n"); force_send_socket(udp:EXTERNAL_IP:5060); route(RELAY); exit; } # Dispatch requests route[DISPATCH] { # check if requested number is active on the old cluster system $var(foo) = sql_xquery("altdb", "select LAUF, char_length(KDRUFNUMMER) as RN_LEN from PROGTABLE where '$(tU{s.numeric})' like CONCAT(KDRUFNUMMER, '%') and AKTIV_AB < NOW() and AKTIV_BIS > NOW() order by RN_LEN desc", "resultset"); xlog("L_INFO", "sql_xquery result = $var(foo) \n"); if ($var(foo) == 1) { # number IS active -> route to old system (dispatcher group 2) xlog("L_INFO", "Routing to old System dispatcher\n"); if(!ds_select_dst(2, 4)) { # no active system found (not answerering to OPTIONS) xlog("L_ERR", "Failed to route to old System!"); send_reply("503", "Service temporary not available"); exit; } } else { # number NOT active on OLD system -> route to new system and loadbalance (dispatcher group 1) xlog("L_INFO", "Routing to default dispatcher\n"); if(!ds_select_dst(1, 4)) { xlog("L_ERR", "Failed to route to default system"); send_reply("503", "Service temporary not available"); exit; } } sql_result_free("resultset"); t_on_failure("RTF_DISPATCH"); return; } # Sample failure route failure_route[RTF_DISPATCH] { if (t_is_canceled()) { exit; } # next DST - only for 500 or local timeout if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied())) { if(ds_next_dst()) { t_on_failure("RTF_DISPATCH"); route(RELAY); exit; } } }