Browse Source

added comments and fixed association bug were with maps back to itself

3.12
K Anderson 15 years ago
parent
commit
41fa401570
1 changed files with 118 additions and 27 deletions
  1. +118
    -27
      opensips/opensips.cfg

+ 118
- 27
opensips/opensips.cfg View File

@ -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");
} }
} }

Loading…
Cancel
Save