|
|
@ -291,11 +291,14 @@ modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") |
|
|
###################################################################### |
|
|
###################################################################### |
|
|
route |
|
|
route |
|
|
{ |
|
|
{ |
|
|
|
|
|
# log the basic info regarding this call |
|
|
xlog("L_INFO", "$ci|start|recieved $oP request $rm $ou"); |
|
|
xlog("L_INFO", "$ci|start|recieved $oP request $rm $ou"); |
|
|
xlog("L_INFO", "$ci|log|source $si:$sp"); |
|
|
xlog("L_INFO", "$ci|log|source $si:$sp"); |
|
|
xlog("L_INFO", "$ci|log|from $fu"); |
|
|
xlog("L_INFO", "$ci|log|from $fu"); |
|
|
xlog("L_INFO", "$ci|log|to $tu"); |
|
|
xlog("L_INFO", "$ci|log|to $tu"); |
|
|
|
|
|
|
|
|
|
|
|
# check that hop cound for this request and make sure it is under 10 |
|
|
|
|
|
# to prevent endless loops |
|
|
if (!mf_process_maxfwd_header("10")) |
|
|
if (!mf_process_maxfwd_header("10")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_WARN", "$ci|end|to many hops"); |
|
|
xlog("L_WARN", "$ci|end|to many hops"); |
|
|
@ -305,6 +308,10 @@ route |
|
|
exit; |
|
|
exit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# this check detemines if the opensips has routed the request to itself, |
|
|
|
|
|
# this happens because the server is the destination of the request but |
|
|
|
|
|
# we mangle it to send it else where. When that mangeling fails and we |
|
|
|
|
|
# still relay it then it just comes right back to us... |
|
|
if (src_ip==myself) |
|
|
if (src_ip==myself) |
|
|
{ |
|
|
{ |
|
|
xlog("L_WARN", "$ci|end|sourced from this server"); |
|
|
xlog("L_WARN", "$ci|end|sourced from this server"); |
|
|
@ -312,6 +319,8 @@ route |
|
|
exit; |
|
|
exit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# currently we dont support subscribe in whistle so to keep the noise down |
|
|
|
|
|
# just end the request here. For options just end the request here as well. |
|
|
if (is_method("OPTIONS|SUBSCRIBE")) |
|
|
if (is_method("OPTIONS|SUBSCRIBE")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_NOTICE", "$ci|end|unsupported method"); |
|
|
xlog("L_NOTICE", "$ci|end|unsupported method"); |
|
|
@ -321,7 +330,9 @@ route |
|
|
exit; |
|
|
exit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# if the source IP/port are in one of the server dispatch lists |
|
|
|
|
|
# then this request originated from one of our media servers, mark it |
|
|
|
|
|
# as such by setting flag 26 |
|
|
if (ds_is_in_list("$si", "$sp", "1") || ds_is_in_list("$si", "$sp", "2")) |
|
|
if (ds_is_in_list("$si", "$sp", "1") || ds_is_in_list("$si", "$sp", "2")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|inception on-net"); |
|
|
xlog("L_INFO", "$ci|log|inception on-net"); |
|
|
@ -329,11 +340,16 @@ route |
|
|
# Flag 26 marks the source as a on-net server |
|
|
# Flag 26 marks the source as a on-net server |
|
|
setflag(26); |
|
|
setflag(26); |
|
|
} |
|
|
} |
|
|
|
|
|
# if the request source IP/port was not in any dispatcher lists |
|
|
|
|
|
# this this originated outside our equipment (carrier, client, ect) |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|inception off-net"); |
|
|
xlog("L_INFO", "$ci|log|inception off-net"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# if the to header has a tag attached then it implies this request |
|
|
|
|
|
# has been processed by us before (IE: a media server has added |
|
|
|
|
|
# its tag on the to header in prior messages) |
|
|
if (has_totag()) |
|
|
if (has_totag()) |
|
|
{ |
|
|
{ |
|
|
# sequential request within a dialog should |
|
|
# sequential request within a dialog should |
|
|
@ -342,7 +358,9 @@ route |
|
|
{ |
|
|
{ |
|
|
append_hf("P-hint: rr-enforced\r\n"); |
|
|
append_hf("P-hint: rr-enforced\r\n"); |
|
|
|
|
|
|
|
|
if (isflagset(26) && is_method("ACK")) |
|
|
|
|
|
|
|
|
# if the request is an ACK from our media servers with a IP in the from domain |
|
|
|
|
|
# then bump the association |
|
|
|
|
|
if ($(fd{ip.isip}) && isflagset(26) && is_method("ACK")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|maintaining contact association to media server $fd"); |
|
|
xlog("L_INFO", "$ci|log|maintaining contact association to media server $fd"); |
|
|
|
|
|
|
|
|
@ -373,6 +391,8 @@ route |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# request with a to tag that cant be routed loosly and is not an ACK |
|
|
|
|
|
# ignor eand discard |
|
|
xlog("L_WARN", "$ci|end|could not route in dialog"); |
|
|
xlog("L_WARN", "$ci|end|could not route in dialog"); |
|
|
|
|
|
|
|
|
sl_send_reply("486", "PC Load Letter"); |
|
|
sl_send_reply("486", "PC Load Letter"); |
|
|
@ -380,7 +400,7 @@ route |
|
|
exit; |
|
|
exit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
# CANCEL processing |
|
|
|
|
|
|
|
|
# if the request is to cancel a transaction process it now |
|
|
if (is_method("CANCEL")) |
|
|
if (is_method("CANCEL")) |
|
|
{ |
|
|
{ |
|
|
# If this cancel is part of a transaction |
|
|
# If this cancel is part of a transaction |
|
|
@ -391,6 +411,8 @@ route |
|
|
|
|
|
|
|
|
route(1); |
|
|
route(1); |
|
|
} |
|
|
} |
|
|
|
|
|
# if the cancel does not belong to a known transaction or a |
|
|
|
|
|
# request that has not progressed outside this server dont relay it |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
xlog("L_NOTICE", "$ci|end|no matching transaction"); |
|
|
xlog("L_NOTICE", "$ci|end|no matching transaction"); |
|
|
@ -403,7 +425,9 @@ route |
|
|
# and do standard processing of the message |
|
|
# and do standard processing of the message |
|
|
t_check_trans(); |
|
|
t_check_trans(); |
|
|
|
|
|
|
|
|
# preloaded route checking |
|
|
|
|
|
|
|
|
# Except for an ACK no request should have a route set with no to tag, this would |
|
|
|
|
|
# indicate that the intial request has the Route headers and is likely someone trying |
|
|
|
|
|
# to get us to send the request were they want |
|
|
if (loose_route()) |
|
|
if (loose_route()) |
|
|
{ |
|
|
{ |
|
|
if (!is_method("ACK")) |
|
|
if (!is_method("ACK")) |
|
|
@ -416,8 +440,12 @@ route |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# If the request is a register we will pass it along but we need |
|
|
|
|
|
# to add the path header (along with the received IP/port info) |
|
|
if (is_method("REGISTER")) |
|
|
if (is_method("REGISTER")) |
|
|
{ |
|
|
{ |
|
|
|
|
|
# if we fail to add the path header then dont let it |
|
|
|
|
|
# register because it will cause issues later... |
|
|
if (!add_path_received()) |
|
|
if (!add_path_received()) |
|
|
{ |
|
|
{ |
|
|
xlog("L_ERR", "$ci|end|unable to add path"); |
|
|
xlog("L_ERR", "$ci|end|unable to add path"); |
|
|
@ -430,19 +458,21 @@ route |
|
|
xlog("L_INFO", "$ci|log|added path"); |
|
|
xlog("L_INFO", "$ci|log|added path"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
# is from media servers |
|
|
|
|
|
|
|
|
# if the request is from on of our media servers then dont change the routing |
|
|
if (isflagset(26)) |
|
|
if (isflagset(26)) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|originated from internal source"); |
|
|
xlog("L_INFO", "$ci|log|originated from internal source"); |
|
|
} |
|
|
} |
|
|
# not from media severs has a contact uri and is in memcache |
|
|
|
|
|
|
|
|
# if the request is not from our media severs but has a contact uri in memcache |
|
|
|
|
|
# then change the routing to go to the server previously associated with it. |
|
|
else if ($ct.fields(uri) && cache_fetch("memcached_callid_hash", "$(ct.fields(uri){uri.user})", $avp(i:55))) |
|
|
else if ($ct.fields(uri) && cache_fetch("memcached_callid_hash", "$(ct.fields(uri){uri.user})", $avp(i:55))) |
|
|
{ |
|
|
{ |
|
|
$rd = $avp(i:55); |
|
|
$rd = $avp(i:55); |
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|log|contact $(ct.fields(uri){uri.user}) is associated with media server"); |
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|log|contact $(ct.fields(uri){uri.user}) is associated with media server $rd"); |
|
|
} |
|
|
} |
|
|
# not from media servers and call id is in memcache |
|
|
|
|
|
|
|
|
# if the request is not from our media severs but has a call-id in memcache |
|
|
|
|
|
# then change the routing to go to the server previously associated with it. |
|
|
else if (cache_fetch("memcached_callid_hash", "$ci", $avp(i:55))) |
|
|
else if (cache_fetch("memcached_callid_hash", "$ci", $avp(i:55))) |
|
|
{ |
|
|
{ |
|
|
$rd = $avp(i:55); |
|
|
$rd = $avp(i:55); |
|
|
@ -456,15 +486,26 @@ route |
|
|
cache_store("memcached_callid_hash", "$(ct.fields(uri){uri.user})", "$rd", 3600); |
|
|
cache_store("memcached_callid_hash", "$(ct.fields(uri){uri.user})", "$rd", 3600); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
# not from media servers and no information in memcache |
|
|
|
|
|
|
|
|
# if the request is not from our media servers and no associations in memcache |
|
|
|
|
|
# then try to distribute to a media server |
|
|
|
|
|
else if (ds_select_domain("1", "4")) |
|
|
|
|
|
{ |
|
|
|
|
|
xlog("L_INFO", "$ci|log|routing call to arbitrary media server $rd"); |
|
|
|
|
|
} |
|
|
|
|
|
# if no media server could be set with ds_select_domain and there is no existing |
|
|
|
|
|
# association then we have no way to route this call, terminate |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
ds_select_domain("1", "4"); |
|
|
|
|
|
|
|
|
xlog("L_ERR", "$ci|end|no servers avaliable"); |
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|log|routing call to arbitrary media server"); |
|
|
|
|
|
|
|
|
sl_send_reply("486", "All servers busy"); |
|
|
|
|
|
|
|
|
|
|
|
exit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
# record routing |
|
|
|
|
|
|
|
|
# for all initial request (not having been processed above in the has_totag) |
|
|
|
|
|
# that are not a register or message add this sever to the route set on the |
|
|
|
|
|
# request so subsequent messages come through this server |
|
|
if (!is_method("REGISTER|MESSAGE")) |
|
|
if (!is_method("REGISTER|MESSAGE")) |
|
|
{ |
|
|
{ |
|
|
# Record the route that this request has taken |
|
|
# Record the route that this request has taken |
|
|
@ -481,34 +522,52 @@ route[1] |
|
|
{ |
|
|
{ |
|
|
route("nat_test_and_correct"); |
|
|
route("nat_test_and_correct"); |
|
|
|
|
|
|
|
|
|
|
|
# if the request domain is an IP and it exists in the list of our media servers (irregardless of the port) |
|
|
|
|
|
# then... |
|
|
|
|
|
# 1. remove any X-AUTH-IP headers so we will be the only one to set it |
|
|
|
|
|
# 2. set the X-AUTH-IP header for freeswitch ACLs |
|
|
|
|
|
# 3. set the final reply timer to two seconds, so we failover faster |
|
|
|
|
|
# 4. arm a logging branch for replies |
|
|
|
|
|
# 5. arm a failure branch that will try another one of our media servers when possible |
|
|
if ($(rd{ip.isip}) && (ds_is_in_list("$rd", "", "1") || ds_is_in_list("$rd", "", "2"))) |
|
|
if ($(rd{ip.isip}) && (ds_is_in_list("$rd", "", "1") || ds_is_in_list("$rd", "", "2"))) |
|
|
{ |
|
|
{ |
|
|
remove_hf("X-AUTH-IP"); |
|
|
remove_hf("X-AUTH-IP"); |
|
|
|
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|log|X-AUTH-IP: $si"); |
|
|
|
|
|
|
|
|
append_hf("X-AUTH-IP: $si\r\n"); |
|
|
append_hf("X-AUTH-IP: $si\r\n"); |
|
|
|
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|log|provisional reply required in 2 seconds"); |
|
|
|
|
|
|
|
|
$avp(s:final_reply_timer) = 2; |
|
|
$avp(s:final_reply_timer) = 2; |
|
|
|
|
|
|
|
|
t_on_reply("on_net_reply"); |
|
|
t_on_reply("on_net_reply"); |
|
|
|
|
|
|
|
|
t_on_failure("on_net_fault"); |
|
|
t_on_failure("on_net_fault"); |
|
|
} |
|
|
} |
|
|
|
|
|
# if the request domain is not an IP or in our list of media servers then |
|
|
|
|
|
# assume it is going somewhere outside our control and give that equipment |
|
|
|
|
|
# longer to respond. Also arm a branch to log the replies |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
|
|
|
xlog("L_INFO", "$ci|log|provisional reply required in 6 seconds"); |
|
|
|
|
|
|
|
|
$avp(s:final_reply_timer) = 6; |
|
|
$avp(s:final_reply_timer) = 6; |
|
|
|
|
|
|
|
|
t_on_reply("off_net_reply"); |
|
|
t_on_reply("off_net_reply"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!t_relay()) |
|
|
|
|
|
|
|
|
# try to send the request on its way, if it fails send back a |
|
|
|
|
|
# stateless error to the requestor |
|
|
|
|
|
if (t_relay()) |
|
|
{ |
|
|
{ |
|
|
xlog("L_ERR", "$ci|end|unable to relay message"); |
|
|
|
|
|
|
|
|
|
|
|
sl_reply_error(); |
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|pass|$rd"); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|pass|$rd"); |
|
|
|
|
|
|
|
|
xlog("L_ERR", "$ci|end|unable to relay message"); |
|
|
|
|
|
|
|
|
|
|
|
sl_reply_error(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
exit; |
|
|
exit; |
|
|
@ -516,33 +575,40 @@ route[1] |
|
|
|
|
|
|
|
|
route[nat_test_and_correct] |
|
|
route[nat_test_and_correct] |
|
|
{ |
|
|
{ |
|
|
|
|
|
# check if the request is from a client behind NAT, and fix if so... |
|
|
|
|
|
# this check looks at: |
|
|
|
|
|
# 1. if client has a private IP address (as defined by RFC1918) in the Contact field of the SIP message |
|
|
|
|
|
# 2. if client has contacted OpenSIPS from an address that is different from the one in the Via field |
|
|
if (client_nat_test("3")) |
|
|
if (client_nat_test("3")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|via address differs from source or RFC1918 address in contact"); |
|
|
xlog("L_INFO", "$ci|log|via address differs from source or RFC1918 address in contact"); |
|
|
|
|
|
|
|
|
|
|
|
# adds the rport parameter to the first Via header |
|
|
force_rport(); |
|
|
force_rport(); |
|
|
|
|
|
|
|
|
#xlog("L_INFO", "$ci|log|forced rport"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# will replace the IP and port in the Contact header with the IP and port |
|
|
|
|
|
# the SIP message was received from |
|
|
fix_contact(); |
|
|
fix_contact(); |
|
|
|
|
|
|
|
|
#xlog("L_INFO", "$ci|log|fixed contact"); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# if the request has a body see if it needs NAT corrections as well, |
|
|
|
|
|
# this check looks at: |
|
|
|
|
|
# 8. SDP is searched for occurrence of RFC1918 addresses |
|
|
if (has_body("application/sdp") && nat_uac_test("8")) |
|
|
if (has_body("application/sdp") && nat_uac_test("8")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|SDP contains a RFC1918 address"); |
|
|
xlog("L_INFO", "$ci|log|SDP contains a RFC1918 address"); |
|
|
|
|
|
|
|
|
#xlog("L_INFO", "$ci|log|rewrite SDP connection data with source address"); |
|
|
|
|
|
|
|
|
|
|
|
#xlog("L_INFO", "$ci|log|rewrite SDP origin with source address "); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# alters the SDP information in order to facilitate NAT traversal. |
|
|
|
|
|
# 2. rewrite media IP address (c=) with source IP |
|
|
|
|
|
# 8. rewrite IP from origin description (o=) with source IP |
|
|
fix_nated_sdp("10"); |
|
|
fix_nated_sdp("10"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
onreply_route[off_net_reply] |
|
|
onreply_route[off_net_reply] |
|
|
{ |
|
|
{ |
|
|
|
|
|
# this branch handles replies that are comming from equipment |
|
|
|
|
|
# outside our control, just logging and NAT corrections |
|
|
xlog("L_INFO", "$ci|start|recieved off-net reply $rs $rr"); |
|
|
xlog("L_INFO", "$ci|start|recieved off-net reply $rs $rr"); |
|
|
xlog("L_INFO", "$ci|log|source $si:$sp"); |
|
|
xlog("L_INFO", "$ci|log|source $si:$sp"); |
|
|
|
|
|
|
|
|
@ -553,11 +619,16 @@ onreply_route[off_net_reply] |
|
|
|
|
|
|
|
|
onreply_route[on_net_reply] |
|
|
onreply_route[on_net_reply] |
|
|
{ |
|
|
{ |
|
|
|
|
|
# this branch handles replies that are comming from our |
|
|
|
|
|
# media server, just logging and NAT corrections |
|
|
xlog("L_INFO", "$ci|start|recieved on-net reply $rs $rr"); |
|
|
xlog("L_INFO", "$ci|start|recieved on-net reply $rs $rr"); |
|
|
xlog("L_INFO", "$ci|log|source $si:$sp"); |
|
|
xlog("L_INFO", "$ci|log|source $si:$sp"); |
|
|
|
|
|
|
|
|
route("nat_test_and_correct"); |
|
|
route("nat_test_and_correct"); |
|
|
|
|
|
|
|
|
|
|
|
# if one of our media servers has replied with a 407 or 401 associate |
|
|
|
|
|
# this call-id with that media server so the next "initial" requests |
|
|
|
|
|
# go to it (IE: the reply to the challenge) |
|
|
if (t_check_status("(407)|(401)")) |
|
|
if (t_check_status("(407)|(401)")) |
|
|
{ |
|
|
{ |
|
|
cache_store("memcached_callid_hash", "$ci ", "$si", 60); |
|
|
cache_store("memcached_callid_hash", "$ci ", "$si", 60); |
|
|
@ -570,6 +641,8 @@ onreply_route[on_net_reply] |
|
|
|
|
|
|
|
|
failure_route[on_net_fault] |
|
|
failure_route[on_net_fault] |
|
|
{ |
|
|
{ |
|
|
|
|
|
# if the failure cause was due to the transaction being |
|
|
|
|
|
# cancelled then we are complete |
|
|
if (t_was_cancelled()) |
|
|
if (t_was_cancelled()) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|end|transaction was cancelled"); |
|
|
xlog("L_INFO", "$ci|end|transaction was cancelled"); |
|
|
@ -577,6 +650,8 @@ failure_route[on_net_fault] |
|
|
exit; |
|
|
exit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# if the failure case was soemthing that we should recover |
|
|
|
|
|
# from then try to find a new media server |
|
|
if (t_check_status("(408)|(5[0-9][0-9])")) |
|
|
if (t_check_status("(408)|(5[0-9][0-9])")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|start|recieved or generated negative reply"); |
|
|
xlog("L_INFO", "$ci|start|recieved or generated negative reply"); |
|
|
@ -584,12 +659,24 @@ failure_route[on_net_fault] |
|
|
|
|
|
|
|
|
xlog("L_ERR", "$ci|log|moving media server $rd to probing mode"); |
|
|
xlog("L_ERR", "$ci|log|moving media server $rd to probing mode"); |
|
|
|
|
|
|
|
|
|
|
|
# flag the media server that failed and start sending SIP pings |
|
|
|
|
|
# when it begins responding put it back in the lsit |
|
|
ds_mark_dst("p"); |
|
|
ds_mark_dst("p"); |
|
|
|
|
|
|
|
|
if(ds_select_domain("1", "4")) |
|
|
|
|
|
|
|
|
# keep track of the original request domain so we can detemine |
|
|
|
|
|
# if ds_select_domain chooses the same domain... |
|
|
|
|
|
$avp(s:old_rd)=$rd; |
|
|
|
|
|
|
|
|
|
|
|
# try to find a new media server to send the calls to, this is |
|
|
|
|
|
# taking advantage of a bug since ds_select_domain is not supposed |
|
|
|
|
|
# to be using in the failover branch (but it is necessary in our |
|
|
|
|
|
# configuration). |
|
|
|
|
|
if(ds_select_domain("1", "4") && $avp(s:old_rd) != $rd) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|routing call to arbitrary media server"); |
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|log|routing call to arbitrary media server $rd"); |
|
|
|
|
|
|
|
|
|
|
|
# if the request has a contact and is an INVITE then store the new |
|
|
|
|
|
# association |
|
|
if ($ct.fields(uri) && is_method("INVITE")) |
|
|
if ($ct.fields(uri) && is_method("INVITE")) |
|
|
{ |
|
|
{ |
|
|
xlog("L_INFO", "$ci|log|associated contact $(ct.fields(uri){uri.user}) with media server $rd"); |
|
|
xlog("L_INFO", "$ci|log|associated contact $(ct.fields(uri){uri.user}) with media server $rd"); |
|
|
@ -599,11 +686,15 @@ failure_route[on_net_fault] |
|
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|pass|$rd"); |
|
|
xlog("L_INFO", "$ci|pass|$rd"); |
|
|
|
|
|
|
|
|
|
|
|
# reset the final reply timer |
|
|
$avp(s:final_reply_timer) = 2; |
|
|
$avp(s:final_reply_timer) = 2; |
|
|
|
|
|
|
|
|
|
|
|
# relay the request to the new media server |
|
|
t_relay(); |
|
|
t_relay(); |
|
|
|
|
|
|
|
|
exit; |
|
|
exit; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
xlog("L_ERR", "$ci|end|no other media servers avaliable"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |