Hi,
I was wondering on OpenSER and came to a Question: How can call routing to SIP gateways be done based on their capacity? Lets say we have two SIP gateways each capable of handling 60 cuncurrent calls. How could I tell openser to forward the call number 61 to the next gateway? How would open ser know if the first gateway has free resources (previuos calls ended), and so on.
Thanks,
Hamid
On Mon, 2006-07-17 at 01:20 +0330, Hamid Ali Asgari wrote:
I was wondering on OpenSER and came to a Question: How can call routing to SIP gateways be done based on their capacity? Lets say we have two SIP gateways each capable of handling 60 cuncurrent calls. How could I tell openser to forward the call number 61 to the next gateway? How would open ser know if the first gateway has free resources (previuos calls ended), and so on.
Personally I would use the dispatcher module to distribute your calls over both media gateways. You can always handle a failure response from one of the media gateways if it is full and try the next gateway.
Cheers, Peter
Hamid,
If your sip gateways respond with an error when they reach capacity then this is a fairly easy task. You would put a t_on_failure("1") just before your t_relay() to the gateway of choice. Something like:
t_on_failure("1"); rewritehostport("gatewayip:gatewayport"); if (!t_relay()) { sl_reply_error(); }
You would then write a function in your script like:
failure_route[1] { rewritehostport("backupip:backupport"); append_branch(); t_relay(); }
This will work assuming that your primary gateway at gatewayip returns an error if it can't make the outbound call.
I haven't used the dispatcher, so can't comment on that.
-g
On Jul 16, 2006, at 9:23 PM, Peter Childs wrote:
On Mon, 2006-07-17 at 01:20 +0330, Hamid Ali Asgari wrote:
I was wondering on OpenSER and came to a Question: How can call routing to SIP gateways be done based on their capacity? Lets say we have two SIP gateways each capable of handling 60 cuncurrent calls. How could I tell openser to forward the call number 61 to the next gateway? How would open ser know if the first gateway has free resources (previuos calls ended), and so on.
Personally I would use the dispatcher module to distribute your calls over both media gateways. You can always handle a failure response from one of the media gateways if it is full and try the next gateway.
Cheers, Peter
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
I would probably suggest adding a few things to non-dispatcher example.
For example, if your mediagateway reports busy (486) or not found (404) do you really want to try via the next media gateway???
By adding a handler to reset the failure handler when a provisional response (ie ringing 180 or progressing 183) is received then we should stop (perhaps) some failures hitting failure_route...
It would pay to test well with your gateways and different conditions (ie end point is busy, end point does not exist, end point does not answer etc...) and if need be exclude them from failure_route retries...
t_on_failure("1");
t_on_reply("1");
rewritehostport("gatewayip:gatewayport"); if (!t_relay()) { sl_reply_error(); }
onreply_route[1] { if( status =~ "18[0-9]" ) { t_on_failure("0"); } }
failure_route[1] { rewritehostport("backupip:backupport"); append_branch(); t_relay(); }
Example of stateful dispatcher with failover....
You need a file called 'dispatcher.list' with something like this in it...
1 sip:gateway1:5060 1 sip:gateway2:5060 1 sip:gateway3:5060
-- openser.cfg -- example with stateful dispatcher + failover (need OpenSER 1.1.x)
mpath = "/opt/openser/lib/openser/modules"
loadmodule "sl.so" loadmodule "tm.so" loadmodule "rr.so" loadmodule "maxfwd.so" loadmodule "xlog.so" loadmodule "dispatcher.so"
# ----------------- setting module-specific parameters ---------------
# -- tm parmas --
# how long to keep a transaction in memory after a final response to # catch things that are just lagged -- default is 5 secs modparam("tm", "wt_timer", 30)
# timer for response to a request modparam("tm", "fr_timer", 2)
# timer for final response after getting a provisional response # ie timer to get say a '200' after getting a '100 trying...' # NB -- this shouldn't need to be set so high, and is basically ignored # as 1) we cancel the failure_route on getting a provisional # 2) network timeouts will be less than this... modparam("tm", "fr_inv_timer", 120)
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- dispatcher params -- # we are in fallover mode... set flag=2 modparam("dispatcher", "flags", 2 )
# ------------------------- request routing logic -------------------
# main routing logic
route{ # initial sanity checks -- messages with # max_forwards==0, or excessively long requests if (!mf_process_maxfwd_header("10")) { xlog( "L_NOTICE", "[$Tf] RR: $ci -- Too Many Hops.\n" ); sl_send_reply("483","Too Many Hops"); exit; };
if (msg:len >= 2048 ) { xlog( "L_NOTICE", "[$Tf] RR: $ci -- Message too big.\n" ); sl_send_reply("513", "Message too big"); exit; };
if (loose_route()) { xlog( "L_NOTICE", "[$Tf] RR: $ci -- Loose Route $rm ($rd).\n" ); if (!t_relay()) { sl_reply_error(); }; return; };
if( method=="CANCEL" ){ if( t_check_trans() ){ xlog("L_NOTICE", "[$Tf] RR: $ci -- $rm Relay \n"); t_relay(); return; } else { xlog("L_WARN", "[$Tf] RR: $ci -- $rm HAS NO TRANSACTION\n" ); return; } }
# PSTN Gateways if( uri=~"^sip:0.........@" || uri=~"^sip:1[38]00......@" || uri=~"^sip:13....@" ) { route(1); return; } }
route[1] { # PSTN Routing - Alg4 == Round Robin
ds_select_domain("1","4");
xlog("L_NOTICE", "[$Tf] RR[1]: $ci -- [PSTN] $rm $fU -> $tU via $rd\n");
t_on_reply("1"); t_on_failure("2");
if( !t_relay() ){ xlog( "L_WARN", "[$Tf] RR[1]: $ci -- ERROR - Can not t_relay()\n" ); # perhaps we should do something here?? return; } return; }
onreply_route[1] {
# we are checking here for a progressing return... ie a 180 Ringing or # 183 session progress -- if this occurs we don't care from here on # about failures as a gateway is handling the call...
if( status =~ "18[0-9]" ) { xlog( "L_INFO", "[$Tf] ORR: $ci -- SIP-$rs Reset t_on_failure()\n"); t_on_failure("0"); } else { xlog( "L_INFO", "[$Tf] ORR: $ci -- $rs $rr\n" ); } }
failure_route[2] {
# If fr_timer expires t_check_status("408") is true, although $rs is <null> if( t_check_status("408") ){ xlog( "L_NOTICE", "[$Tf] FR: $ci -- TIMEOUT for Gateway $rd\n" ); } else { xlog( "L_NOTICE", "[$Tf] FR: $ci -- $rs reason $rr\n" ); }
# basically what we do is # 1. not worry about reasonable failures (ie busy, wrong number etc...) # 2. go to next destination gateway # 3. if no destination gateway then 503 (service unavailable)
# 403 -- typically ISDN network says 'not a valid number' etc.. if( t_check_status("403") ){ xlog("L_NOTICE", "[$Tf] FR: $ci -- SIP-$rs Forbidden -> ISDN Cause Code 1\n" ); return; }
# 408 -- timeout -- typically the end party has not answered # Since we cancel t_on_failure() on a provisional response we should not be # getting a 408 timeout from a gateway at this stage.. it will just "fall through" #if( t_check_status("408") ){ # xlog("L_NOTICE", "[$Tf] FR: $ci -- SIP-$rs Timeout\n" ); # return; #}
# 486 -- User Busy if( t_check_status("486") ){ xlog("L_NOTICE", "[$Tf] FR: $ci -- SIP-$rs Destination Busy\n" ); return; }
# 487 -- Request Cancelled (usually in response to a CANCEL transaction) if( t_check_status("487") ){ xlog("L_NOTICE", "[$Tf] FR: $ci -- SIP-$rs Request Cancelled\n" ); return; }
# ok... so at this stage we try the next gateway (unless we don't have one) # if no next gateway we bail... if( ds_next_domain() ){ t_on_reply("1"); t_on_failure("2"); xlog( "L_NOTICE", "[$Tf] FR: $ci Next gateway $fU -> $tU via $rd\n" ); if( !t_relay() ){ xlog( "L_WARN", "[$Tf] FR: $ci -- ERROR - Can not t_relay()\n" ); # perhaps we should do something here?? return; } return; } else { xlog( "L_WARN", "[$Tf] FR: $ci No more buscuits in the biscuit tin -> 503.\n" ); t_reply("503", "Service unavailable -- no more gateways" ); return; }
}
Hamid Ali Asgari writes:
I was wondering on OpenSER and came to a Question: How can call routing to SIP gateways be done based on their capacity?
openser lcr module doesn't currently support gateway weights. it routes requests to gws of same priority randomly.
Lets say we have two SIP gateways each capable of handling 60 cuncurrent calls. How could I tell openser to forward the call number 61 to the next gateway? How would open ser know if the first gateway has free resources (previuos calls ended), and so on.
openser is not dialog stateful. for that kind of application you would need to design a protocol that allows gws tell their stuff to openser.
-- juha