[Asterisk-Users] Local Channel Call Looping

Darren Sessions dsessions at ionosphere.net
Thu Jan 26 10:13:12 MST 2006


*** If anyone has a better way of doing this, please post to the list. I 
hadn't seen anything on this list or in channel.c/chan_local.c - which 
prompted this email ***

I'm not sure how many VoIP providers out there are using Asterisk as a 
service platform like we do, but I thought I'd share an experience with 
call looping that was racking my brain with the list.

One of the features we offer our customers, is of course, call 
forwarding. We take a call in and spit it back out to whatever the call 
forward number is set by the customer.

With our particular proxy setup, if a call originates from * to the 
proxy it will never loop back to *; this prevents SIP call loops.

In *, for an on-net call forward number, we would use the dial command 
to call (if it was registered) the customer's device with SIP via the 
proxy, and also dial a local channel to process any of the 'forward to' 
customer's features; again, this is for an on-net call.

The problem was that if when we dial the local channel and that customer 
had forwarded calls to the first number or calls were setup to forward 
from cust1 to cust2 to cust3 to cust1, we were getting an infinite local 
channel loop. As you can imagine, the load on * was off the charts.

The solution to the problem finally ended up being to set inherited 
channel variables.

First, we'd read/parse the channel variable to determine if the call was 
coming in anything other than a local channel. If it was, a variable 
with that called number label was immediately set to a value of 1 - i.e. 
the first in the chain.

Next, an addition variable with the 'call forward to' number was also 
given a value of 1, and then the call was processed. When the new local 
channel for the 'forward to' number was spawned, and assuming that call 
forwarding was set on that number, the process would repeat with this 
inherited variable label scheme.

The catch is that in each iteration at the same time the call forward to 
number is being labeled, the system would check that variable for a 
value before it tried to assign one. If the variable had a value, it was 
safe to assume that it had already been processed in the call chain 
somewhere and therefore the system would be looping the call if it 
continued.

Here are some sanitized Perl based AGI excerpts that accomplish this:


sub callfwd_loop_check
{
       my %v;
       ($v{callednum},$v{cfnum}) = @_;
       $v{num} = $AGI->get_variable($v{cfnum});
       if ($v{num})
       {
               debug(" Call Loop Anaylsis for ".$v{callednum}." = 
LOOPING");
               return(1);
       }
       else
       {
               debug(" Call Loop Anaylsis for ".$v{callednum}." = NO 
LOOP");
               $AGI->exec('Set',"__".$v{cfnum}."=".$v{callednum})
       }
       return;
}

$AGI->exec('Set',"__".$callednumber."=1") if ($calltype !~/^Local/);

if (callfwd_loop_check($callednumber,$callfwdtonum))
{
   return;
}

$AGI->exec('Dial',"Local/+".$callfwdtonum."\@localcontext\&SIP/+".$callfwdtonum."\@sipproxy|180"); 



I hope this all makes sense! :)

Thanks,

- Darren



More information about the asterisk-users mailing list