diff --git a/kamailio/default.cfg b/kamailio/default.cfg index 3441d0f7..6d42d293 100644 --- a/kamailio/default.cfg +++ b/kamailio/default.cfg @@ -692,10 +692,6 @@ route[EXTERNAL_TO_INTERNAL_RELAY] } #!endif - #!ifdef FAST_PICKUP_ROLE - route(FAST_PICKUP_REFER); - #!endif - remove_hf_re("^X-.*"); append_hf("X-AUTH-IP: $si\r\n"); append_hf("X-AUTH-PORT: $sp\r\n"); @@ -761,10 +757,6 @@ onreply_route[INTERNAL_REPLY] route(DOS_PREVENTION); #!endif - #!ifdef FAST_PICKUP_ROLE - route(FAST_PICKUP_REPLY); - #!endif - if (is_method("INVITE") && !isflagset(FLAG_SESSION_PROGRESS) && t_check_status("(180)|(183)|(200)") diff --git a/kamailio/defs.cfg b/kamailio/defs.cfg index 6466730b..1461887f 100644 --- a/kamailio/defs.cfg +++ b/kamailio/defs.cfg @@ -107,4 +107,7 @@ #!trydef KZ_TLS_REGISTRAR_PORT 7000 #!endif +#!trydef KZ_FAST_PICKUP_COOKIES 1 +#!trydef KZ_FAST_PICKUP_REALTIME 1 + # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/fast-pickup-role.cfg b/kamailio/fast-pickup-role.cfg index 560c5eb8..d8343d1c 100644 --- a/kamailio/fast-pickup-role.cfg +++ b/kamailio/fast-pickup-role.cfg @@ -2,6 +2,9 @@ modparam("htable", "htable", "park=>size=16;autoexpire=600") modparam("htable", "htable", "fp=>size=8"); +kazoo.fast_pickup_cookies = KZ_FAST_PICKUP_COOKIES descr "maintains a hash table for correlating call-ids with media servers" +kazoo.fast_pickup_realtime = KZ_FAST_PICKUP_REALTIME descr "queries channels api for realtime status of call-id" + route[FAST_PICKUP_START] { $sht(fp=>count) = 0; @@ -66,66 +69,46 @@ route[FAST_PICKUP_ATTEMPT] } } - if($var(replaced_call_id) != "none") { - xlog("L_INFO", "$ci|log|request has replaces call-id $var(replaced_call_id)\n"); - $var(amqp_payload_request) = '{"Event-Category" : "call_event" , "Event-Name" : "channel_status_req", "Call-ID" : "' + $var(replaced_call_id) + '", "Active-Only" : true }'; - $var(amqp_routing_key) = "call.status_req." + $(var(replaced_call_id){kz.encode}); - sl_send_reply("100", "locating your call"); - xlog("L_INFO", "$ci|log|querying cluster for the location of call-id $var(replaced_call_id)\n"); - if(kazoo_query("callevt", $var(amqp_routing_key), $var(amqp_payload_request))) { - $du = $(kzR{kz.json,Switch-URL}); - if($du != $null) { - if($(ru{uri.user}) =~ "\*") { - remove_hf_re("^Replaces"); - append_hf("Replaces: $var(replaced_call_id);a-leg=true\r\n"); - } - xlog("L_INFO", "$ci|log|call-id $var(replaced_call_id) found redirecting call ($(ru{uri.user})) to $du\n"); - route(EXTERNAL_TO_INTERNAL_RELAY); - exit(); - } else { - xlog("L_WARN", "$ci|log|call-id $var(replaced_call_id) not found in cluster, proceeding with normal dispatch\n"); - remove_hf_re("^Replaces"); - } - } else { - remove_hf_re("^Replaces"); + if(@cfg_get.kazoo.fast_pickup_realtime == 1) { + if($var(replaced_call_id) != "none") { + xlog("L_INFO", "$ci|log|request has replaces call-id $var(replaced_call_id)\n"); + $var(amqp_payload_request) = '{"Event-Category" : "call_event" , "Event-Name" : "channel_status_req", "Call-ID" : "' + $var(replaced_call_id) + '", "Active-Only" : true }'; + $var(amqp_routing_key) = "call.status_req." + $(var(replaced_call_id){kz.encode}); + sl_send_reply("100", "locating your call"); + xlog("L_INFO", "$ci|log|querying cluster for the location of call-id $var(replaced_call_id)\n"); + if(kazoo_query("callevt", $var(amqp_routing_key), $var(amqp_payload_request))) { + $du = $(kzR{kz.json,Switch-URL}); + if($du != $null) { + if($(kzR{kz.json,Other-Leg-Call-ID}) == "") { + ## not bridged + $var(rep) = $_s($hdr(Replaces);a-leg=true); + } else { + ## ensure early-only=true + $var(rep) = $_s($(hdr(Replaces){re.subst,/;early-only//});early-only=true); + } + remove_hf_re("^Replaces"); + append_hf("Replaces: $var(rep)\r\n"); + xlog("L_INFO", "$ci|log|call-id $var(replaced_call_id) found redirecting call ($(ru{uri.user})) to $du\n"); + route(EXTERNAL_TO_INTERNAL_RELAY); + exit(); + } else { + xlog("L_WARN", "$ci|log|call-id $var(replaced_call_id) not found in cluster, proceeding with normal dispatch\n"); + } + } else { + xlog("L_WARN", "$ci|log|error querying cluster for call-id $var(replaced_call_id), proceeding with normal dispatch\n"); + } } } ##### CALL-PARK #### - if($(ru{uri.user}) =~ "\*" && $sht(park=>$(ru{uri.user})@$(ru{uri.domain})) != $null) { + if($sht(park=>$(ru{uri.user})@$(ru{uri.domain})) != $null) { $du = $sht(park=>$(ru{uri.user})@$(ruri{uri.domain})); xlog("L_INFO", "$ci|log|redirecting park request to $du\n"); - if ($hdr(Proxy-Authorization) != $null) { - xlog("L_INFO", "$ci|log|removed park redirect\n"); - $sht(park=>$(ru{uri.user})@$(ruri{uri.domain})) = $null; - } route(EXTERNAL_TO_INTERNAL_RELAY); exit(); } } -route[FAST_PICKUP_REFER] -{ - if(!is_method("REFER")) { - return; - } - - $avp(refer_to) = $hdr(Refer-To); - $avp(referred_by) = $hdr(Referred-By); - $avp(refer_to_uri) = $rt; -} - -route[FAST_PICKUP_REPLY] { - if (!is_method("REFER") || !t_check_status("(200)|(202)") ) { - return; - } - - $var(contact) = "sip:" + $(ct{tobody.uri}{uri.host}) + ":" + $(ct{tobody.uri}{uri.port}); - xlog("L_INFO", "$ci|log|caching park info $(avp(refer_to_uri){uri.user})@$(avp(refer_to_uri){uri.domain}) = $var(contact)\n"); - - $sht(park=>$(avp(refer_to_uri){uri.user})@$(avp(refer_to_uri){uri.domain})) = $var(contact); -} - route[FAST_PICKUP_OPTION] { $var(Pickup) = ""; @@ -145,16 +128,31 @@ route[FAST_PICKUP_OPTION] route[FAST_PICKUP_INIT] { $var(AppName) = $(kzE{kz.json,App-Name}); + + ## park redirects without replaces header if($var(AppName) == "park") { - $var(Pickup) = 1; #";a-leg=true"; - } else { - $var(Pickup) = 2; #";early-only=true"; + if($(kzE{kz.json,State}) == "terminated") { + $sht(park=>$(kzE{kz.json,Presence-ID})) = $null; + } else { + $sht(park=>$(kzE{kz.json,Presence-ID})) = $(kzE{kz.json,Switch-URI}); + } + + } + + ## fast pickup with cookies + if(@cfg_get.fast_pickup_cookies == 1) { + if($var(AppName) == "park") { + $var(Pickup) = 1; #";a-leg=true"; + } else { + $var(Pickup) = 2; #";early-only=true"; + } + + $var(Option) = $(var(Pickup){s.encode.hexa}); + $var(Cookie) = $(kzE{kz.json,Switch-URI}{s.md5}); + $var(call_id) = $(kzE{kz.json,Call-ID}); + $var(JObj) = $(kzE{re.subst,/"Call-ID"\s*\:\s*"([^"]*)"/"Call-ID" : "kfp+$var(Option)$var(Cookie)@\1"/}); + xlog("L_INFO", "$var(call_id)|fast|shortcut ($var(Pickup)) kfp+$var(Option)$var(Cookie)@$var(call_id)\n"); } - $var(Option) = $(var(Pickup){s.encode.hexa}); - $var(Cookie) = $(kzE{kz.json,Switch-URI}{s.md5}); - $var(call_id) = $(kzE{kz.json,Call-ID}); - $var(JObj) = $(kzE{re.subst,/"Call-ID"\s*\:\s*"([^\s"]*)"/"Call-ID" : "kfp+$var(Option)$var(Cookie)@\1"/}); - xlog("L_DEBUG", "$ci|init|fast|created shortcut kfp+$var(Option)$var(Cookie)@ for call-id $var(call_id)\n"); } # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab