By analyzing the log created from ngrep, I have draft the following flow. http://fisher.no-ip.com/ngrep/loop.log In line 371, the looping occurs to openser itself. I wonder why openser loop the message itself. Do I need to do something in dial plan to prevent the looping? Any simply way to prevent it? Thanks!
UA (92) OPENSER (228) CISCO (215) -----------INV-------------> <--------trying------------ -------------INV-----------> -------------INV-----------> <----------trying------------ <----------trying------------ <----------183------------ <----------183------------ ---------CANCEL---------> ---------CANCEL---------> <------200 canceling------- <---------OK--------------- <---------487--------------- ---------ACK---------> <----------487------------ ---------CANCEL---------> <------200 canceling------- ---------ACK---------> ---------CANCEL---------> <------200 canceling------- ---------CANCEL---------> CANCEL (looping:line 371) CANCEL (looping) CANCEL (looping) CANCEL (looping) CANCEL (looping) 408 (looping) ...
On 5/10/06, unplug maillisting@gmail.com wrote:
Thanks for help. I have introduced the code below. Sometimes, I can see the logging message "CANCEL without matching transaction ... ignore and discard" in the log. It means it can handle the CANCAL/INVITE racing condition. However, the looping still occured after a series of INVITE/CANCEL operation.
route {
xlog("L_INFO","---[$fU@MR]-$rm---\n"); # ----------------------------------------------------------------- # Sanity Check Section # ----------------------------------------------------------------- if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); return; }; if (msg:len > max_len) { sl_send_reply("513", "Message Overflow"); return; }; #------------------------------------------------------------------ # Accounting section #------------------------------------------------------------------ setflag(1); # ----------------------------------------------------------------- # Record Route Section # ----------------------------------------------------------------- if (method=="INVITE" && client_nat_test("3")) { # INSERT YOUR IP ADDRESS HERE record_route(); add_rr_param(";nat=yes"); } else if (method!="REGISTER") { record_route(); }; # ----------------------------------------------------------------- # Call Tear Down Section # do not send to voicemail if BYE or CANCEL # is used to end call before user pickup or timeout # ----------------------------------------------------------------- if (method=="BYE" || method=="CANCEL") { setflag(10); route(7); end_media_session(); }; if (method=="PRACK") { route(7); }; # ----------------------------------------------------------------- # Loose Route Section # ----------------------------------------------------------------- if (loose_route()) { if (has_totag() && (method=="INVITE" || method=="ACK")) { if (client_nat_test("3")||search("^Route:.*;nat=yes")){ setflag(6); use_media_proxy(); }; }; route(1); return; }; # ----------------------------------------------------------------- # Call Type Processing Section # ----------------------------------------------------------------- if (!is_uri_host_local()) { if (is_from_local() || allow_trusted()) { route(4); route(1); } else { sl_send_reply("403", "Forbidden"); }; return; }; if (method=="CANCEL") { if (!t_check_trans()) { xlog("L_WARN","---CANCEL without matching
transaction ... ignore and discard.\n"); return; } route(1); return; } else if (method=="INVITE") { route(3); return; } else if (method=="REGISTER") { route(2); return; } else if (method=="ACK") { route(1); return; };
lookup("aliases"); if (uri!=myself) { route(4); route(1); return; }; if (!lookup("location")) { sl_send_reply("404", "User Not Found"); return; }; route(1);
}
On 5/8/06, samuel samu60@gmail.com wrote:
Daniel,
There was a thread in serdev with title "INVITE vs. CANCEL race condition" talking about this issue. After that Andrei modified the tm to solve this issue...
After re-reading that thread and what Daniel replied I could refresh my spoiled memory :P: The exact problem happens in two cases: *the CANCEL arrives BEFORE the INVITE, or *it arrives after but you are doing other high-cost processing steps (i.e., DNS lookup (ENUM)) before calling t_relay which will lead to process the CANCEL before creating the transaction.
So I was not fair talking about bugs and replies (1xx) in my previous answers to this thread, aplogies.
Samuel.
2006/5/5, Daniel-Constantin Mierla daniel@voice-system.ro:
Hello,
On 05/05/2006 10:17 AM, samuel wrote:
That's exactly what I mean and I don't know wether in 1.1 it's gonna be solved...Can any core developer shed some light on this??
can you give more details about this problem (web links, description ...).
CANCEL processing is a bit delicate, if you run stateful proxy, tm module takes care to forward the CANCEL to the adequate destination. But if the transaction does not exists, you may end in a loop, if the CANCEL processing does not follow same steps as INVITE.
For stateful proxy, you can check if the INVITE transaction still exists, and if not, drop the CANCEL, see: http://openser.org/docs/modules/1.1.x/tm.html#AEN461
Cheers, Daniel
The "best" way to solve this is to decrement Max-Forwards: header to a really low value (3 or 4 instead of the current minimum 16) BUT BE CAREFULL because you might have problems of failed sessions in remote proxies (it depends a lot on your topology and offered services). With this configuration your loop problem will reduce from the current 16 to 3 or 4.... I repeat THIS COULD INTRODUCE INTEROPERABIOLITY issues.....use it with care.
Another approach would be to increase the number of children so the probability that all openSER children get blocked is really low and the user experience is not affected. In this way you will just see from time to time the loop-effect on your logs and nothing more.
I can not provide you more info...hope I was not wrong and it helped you a little....
Samuel.
2006/5/5, unplug maillisting@gmail.com:
Thanks! Do you mean that the CANCEL matching problem (2nd problem) may be a bug in the openser core and may be solved in the 1.1 version? In the mean time, any suggestion to prevent it (in setting of configuration file) and how can you handle it? Just to want get more information about that problem.
On 5/4/06, samuel samu60@gmail.com wrote:
It looks like the listen and alias statement are properly configured and your openser will likely detect the CANCEL targeted to itself (check the logs). The "problem" is that if you do not add a port to the listen|alias then openSER assumes that the server is listening to all ports. This leads to problems when you have other SIP entities colocated to openSER in the same machine. If you do add port to the listen|alias then ONLY those ports will match the myself condition. From your config file you would match ALL ports because you have the alias set to 10.200.0.228. There was recently a thread about aliases in openser, you might find more info there... From the dokuwiki: "It is necessary to include the port (the value used in the "port=" defintion) in the alias definition otherwise the loose_route() function will not work as expected for local forwards"
So add the 5060 port to the alias and check if it is solved.
About the second problem....it's been a long time since I last checked it so I might be totally wrong and the core developers should provide you more info. The CANCEL matching is something really inside openSER and requires quite changes in the core. I repeat that this might be solved because in SER it has been done so somebody might have ported it to openSER.
Hope it helps, Samuel.
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users