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;
}
}