[Users] ACK Routing: Best practices?

Klaus Darilion klaus.mailinglists at pernau.at
Wed Aug 2 09:45:25 CEST 2006


Hi Carsten!

First I would differ between ACK and CANCEL.

If you use statefull forwarding, then it is sufficient to just t_relay, 
as tm will take care of hop-by-hop canceling. There is no need to 
rewrite the R-URI. There is only one problem: If the INVITE processing 
takes more time, than it may happen that the CANCEL hits the tm module 
before the tm module created a transaction. Thus, I discard CANCEL 
without existing transactions.

ACK: There are 3 kinds of possible ACK.
1. stateless, e.g. if you use sl_send_reply("404",""), then the client 
will send a "stateless" ACK. This ACK will be absorbed by openser as 
soon as it is received and will never enter the routing logic. Thus, we 
do not have to care about them.

2. statefull, sucessful call: The INVITE was answered with 200, thus the 
caller sends an ACK to the callee. This ACK is in-dialog, and thus 
should be routed by the loose_route block (no need to rewrite any URI)

3. statefull, unsuccessful call: The call was rejected or cancelled. 
Thus, we have hop-by-hop ACKs. Thus, the ACK must be handled to the tm 
moudle, which takes care of it (no need to rewrite any URI).

here is how I handle ACK and CANCEL. I did not had any issues with this 
(running now since 1 year).


   if ( is_method("CANCEL") && !t_check_trans() ) {
     # CANCEL without matching INVITE transaction, ignore
     # may happen if the INVITE is slower than the CANCEL
     #  ignore the CANCEL, as the client will retransmit it, and maybe 
next time
     # the INVITE transaction is already created
     xlog("L_WARN","$ci CANCEL without matching transaction ... ignore 
and discard.\n");
     exit;
   }
   route(8);       # disable mediaproxy (needs to see valid CANCEL requests)
   force_send_socket(83.136.32.160:5060);  # force port 5060 as sending port
   if ( is_method("CANCEL") ) {
     # CANCEL with matching INVITE transaction, just
     # t_relay
     xlog("L_INFO","$ci CANCEL with matching transaction ... t_relay.\n");
     t_relay();
     exit;
   }
   # check every message for Remote-Party-Id: header and remove it
   if (is_present_hf("Remote-Party-ID")) {
     xlog("L_INFO", "$ci Remote-Party-ID header present ...removing\n");
     remove_hf("Remote-Party-ID");
   }
   if (loose_route()) {
     # loose route requests are not authenticated
     xlog("L_INFO","$ci beginning loose_route processing...\n");
     route(32);      # handle in-dialog requests
     exit;
   }
   if ( is_method("ACK") ) {
     if ( t_check_trans() ) {
       # non loose-route, but stateful ACK; must be an ACK after a 487
       xlog("L_INFO","$ci local end-to-end ACK for an existent INVITE 
transaction detected ...t_relay()\n");
       t_relay();
     } else {
       xlog("L_WARN","$ci ACK without matching transaction ... ignore 
and discard.\n");
     }
     exit;
   }
   if ( has_totag() ) {
     # in-dialog requests should be handled by loose_route
     # this should be fixed in the client or in openser
     xlog("L_ERR","$ci in-dialog request was not catched by loose_route 
block, 403... \n");
     xlog("L_ERR","$ci this is the complete message:\n");
     xlog("L_ERR","$ci $mb\n");
     sl_send_reply("403","in-dialog request without loose_route is not 
allowed, this is a bug in the client or in this proxy\n");
     exit;
   }
   route(7);       # proxy authentication



regards
Klaus












Carsten Bock wrote:
> Hi everybody,
> 
> Short question: Are there any best practices regarding the routing of 
> ACK Messages?
> Currently we have the following logic implemented:
> 
> route {
>    [...]
>    
> ################################################################################################################## 
> 
>    # Check for Re-Transmissions (not ACK/CANCEL)
>    
> ############################################################################################################### 
> 
>    if ((method != "CANCEL") && (method != "ACK")) {
>        if (t_check_trans()) {
>            log(1, "Re-Transmission detected, message dropped.\n");
>            # Drop the message silently.
>            return;
>        }
>    }
>      
> ################################################################################################################## 
> 
>    # Loose-Routing (RFC3261)
>    
> ############################################################################################################### 
> 
>    if (loose_route()) {
>        route(10);
>        return;
>    }; # if (loose_route()) {      
> ################################################################################################################## 
> 
>    # ACK/CANCEL Messages may be relayed
>    
> ############################################################################################################### 
> 
>    if ((method == "CANCEL") || (method == "ACK")) {
>        if (uri != myself) {
>            #  Und das Paket entsprechend weiterleiten
>            if (!t_relay("udp:outbound_proxy:outbound_proxy_port")) {
>                log(1, "Not possible to relay\n");
>                # Fehler melden
>                sl_reply_error();
>                return;
>            }
>            return;
>        }
>    }
>    [...]
>    
> ################################################################################################################## 
> 
>    # Rest of "normal" Routing logic with number manipulation / Routing 
> to different Gateways / User Authorization/Authentication
>    
> ############################################################################################################### 
> 
> }
> 
> Is there any other method, to improve the routing of ACK/CANCEL 
> Messages? I would like to avoid all the number manipulation, checking 
> and choosing of a proper gateway....
> I thought, this must (somehow) be possible since from a technical 
> perspective the ACK and CANCEL Message can be associated with a 
> corresponding INVITE Message (and the corresponding Transaction).
> I've looked in the manual of the TM-Module and found the following example:
> if ( is_method("CANCEL") ) {
> if ( t_check_trans() )
> t_relay();
> exit;
> }
> (http://openser.org/docs/modules/1.1.x/tm.html#AEN460)
> 
> I guess, this example does not mean, that the URI gets rewritten 
> properly and the CANCEL-/ACK-Message would get properly relayed to the 
> destination, where it is supposed to end.
> Is there any way to do it best? I've seen, that some clients do proper 
> loose-routing for ACK-Messages, but not all clients, so this is not a 
> solution.
> Are there any other suggestions?
> 
> Thanks in advance,
> 
> Carsten
> 
> 
> 
> ____________
> Virus checked by G DATA AntiVirusKit
> 
> 
> 
> _______________________________________________
> Users mailing list
> Users at openser.org
> http://openser.org/cgi-bin/mailman/listinfo/users





More information about the Users mailing list