Thanks Daniel, you’re totally right!

I hadn’t spotted the wrong IP in the ACK, so I’m trying to correct that with 
our provider ;)

If it doesn’t, I’d go for solution number 2 as we have multiple Asterisk behind 
each Kamailio.

Cheers, Francisco.

From: Daniel-Constantin Mierla [mailto:mico...@gmail.com]
Sent: 08 June 2016 22:50
To: Kamailio (SER) - Users Mailing List <sr-users@lists.sip-router.org>; 
Francisco Valentin Vinagrero <francisco.valentin.vinagr...@cern.ch>
Subject: Re: [SR-Users] ACK does not match transaction after stripping Route 
header


Hello,

the problem is that the ACK doesn't have in R-URI the address from Contact 
header in 200ok, as required by RFC.

The R-URI and the Route are both having the IP of Kamailio, so there is no 
other address where to send the ACK.

       ACK sip:10.15.1.30:5060 SIP/2.0
       *Route: sip:10.15.1.30;lr;ftag=SDkbo9901-42090
You have to track why the ACK is not coming with R-URI having the address from 
Contact of 200ok. See how 200ok is received by caller and how caller's devices 
sets the R-URI. Might be the sbc or other hop breaking it.

If you can't fix the device/application messing up the R-URI for the ACK, then 
you can try some solutions in kamailio:

1) use set_contact_alias() for 18x/200ok responses and then handle_ruri_alias() 
for ACK and other requests within dialog.

if(has_totag() && uri==myself && $ru=~";alias=") {
    handle_ruri_alias();
    if($du != $null) {
       $ru = $du;
    }
}
# continue with loose_route(), etc ...

It works if the devices messes up only the host/port of the R-URI in ACK, but 
keeps the other parameters.

2) if 1 doesn't work, use htable to store association between callid+from-tag 
and the contact address of 200ok, then use it for requests within dialog that 
have uri==myself

reply_route {
...
  if(is_method("INVITE") && status=="200") {
      $sht(ct=>$ci::$ft) = $sel(contact.uri);
  }
...
}

request_route {
...
if(has_totag() && uri==myself) {
  if($sht(ct=>$ci::$ft) != $null) {
     $ru = $sht(ct=>$ci::$ft);
  }
}
# continue with loose_route(), etc ...
...
}

You have to set the auto-expire for htable ct to the maximum lifetime for a 
dialog. You can delete the items from ct hash table (or reduce their expire 
value) when processing the BYE or the response to BYE. Note that for bye you 
have to try the combination $ci:$ft as well as $ci:$tt

3) if you have only one asterisk, then if the request has to-tag and a route 
header and uri==myself, then just set $ru to sip:ip:port of asterisk

Cheers,
Daniel
On 08/06/16 12:18, Francisco Valentin Vinagrero wrote:
Hi there,

I’m having an issue in a SBC (ACME) -> KAMAILIO -> Asterisk scenario with an 
ACK that gets ignored in Kamailio because it does not match any transaction.

The INVITE coming from the SBC looks like this (only relevant headers and 
hidden numbers for simplicity – SBC has IP .12 , Kamailio .30 and Asterisk .34)

INVITE sip:mynumber@10.15.1.30:5060 SIP/2.0
Via: SIP/2.0/UDP 10.15.1.12:5060;branch=z9hG4bKdd1m7b00aom47rggc700.1
To: <sip: mynumber@10.15.1.30:5060><sip:mynumber@10.15.1.30:5060>
From: 
<sip:a-number@10.15.1.12;user=phone><sip:a-number@10.15.1.12;user=phone>;tag=SDkbo9901-42090
P-Asserted-Identity: <sip: a-number @10.15.1.12>
Call-ID: SDkbo9901-71a1d17456b829b4c422af61de9eee7e-ao32g50
CSeq: 1 INVITE
Contact: 
<sip:41754112601@10.15.1.12:5060;transport=udp><sip:41754112601@10.15.1.12:5060;transport=udp>

And its forwarded to Asterisk with the Record-Route header:


        INVITE sip: mynumber @10.15.1.30:5060 SIP/2.0
        *Record-Route: 
<sip:10.15.1.30;lr=on;ftag=SDkbo9901-42090><sip:10.15.1.30;lr=on;ftag=SDkbo9901-42090>
        *Via: SIP/2.0/UDP 
10.15.1.30;branch=z9hG4bK1c02.7dc1b94be22d8780df5141f9ba3c5b7b.0
        Via: SIP/2.0/UDP 10.15.1.12:5060;branch=z9hG4bKdd1m7b00aom47rggc700.1
        To: <sip:mynumber@10.15.1.30:5060><sip:mynumber@10.15.1.30:5060>
        From: 
<sip:a-number@10.15.1.12;user=phone><sip:a-number@10.15.1.12;user=phone>;tag=SDkbo9901-42090
        P-Asserted-Identity: <sip:a-number@10.15.1.12><sip:a-number@10.15.1.12>
        Call-ID: SDkbo9901-71a1d17456b829b4c422af61de9eee7e-ao32g50
        CSeq: 1 INVITE
        Contact: 
<sip:a-number@10.15.1.12:5060;transport=udp><sip:a-number@10.15.1.12:5060;transport=udp>


Then, 200 OK from Asterisk:

        SIP/2.0 200 OK
        *Via: SIP/2.0/UDP 
10.15.1.30;rport=5060;received=10.15.1.30;branch=z9hG4bK1c02.7dc1b94be22d8780df5141f9ba3c5b7b.0
        Via: SIP/2.0/UDP 10.15.1.12:5060;branch=z9hG4bKdd1m7b00aom47rggc700.1
        *Record-Route: 
<sip:10.15.1.30;lr;ftag=SDkbo9901-42090><sip:10.15.1.30;lr;ftag=SDkbo9901-42090>
        Call-ID: SDkbo9901-71a1d17456b829b4c422af61de9eee7e-ao32g50
        From: 
<sip:a-number@10.15.1.12;user=phone><sip:a-number@10.15.1.12;user=phone>;tag=SDkbo9901-42090
       To: 
<sip:mynumber@10.15.1.30><sip:mynumber@10.15.1.30>;tag=2e3c2071-c895-4069-afc2-37a19b20637a
        CSeq: 1 INVITE
        Server: Asterisk PBX 13.8.0
        Contact: <sip:10.15.1.34:5060><sip:10.15.1.34:5060>

Which is sent to the SBC like this:

     SIP/2.0 200 OK
        Via: SIP/2.0/UDP 10.15.1.12:5060;branch=z9hG4bKdd1m7b00aom47rggc700.1
        *Record-Route: 
<sip:10.15.1.30;lr;ftag=SDkbo9901-42090><sip:10.15.1.30;lr;ftag=SDkbo9901-42090>
        Call-ID: SDkbo9901-71a1d17456b829b4c422af61de9eee7e-ao32g50
        From: 
<sip:a-number@10.15.1.12;user=phone><sip:a-number@10.15.1.12;user=phone>;tag=SDkbo9901-42090
        To: 
<sip:mynumber@10.15.1.30><sip:mynumber@10.15.1.30>;tag=2e3c2071-c895-4069-afc2-37a19b20637a
        CSeq: 1 INVITE
        Server: Asterisk PBX 13.8.0
        Contact: <sip:10.15.1.34:5060><sip:10.15.1.34:5060>


And finally the SBC sends the ACK:

       ACK sip:10.15.1.30:5060 SIP/2.0
        Via: SIP/2.0/UDP 10.15.1.12:5060;branch=z9hG4bKdt7p9k00dounet8ic600.1
        To: 
<sip:mynumber@10.15.1.30><sip:mynumber@10.15.1.30>;tag=2e3c2071-c895-4069-afc2-37a19b20637a
        From: 
<sip:a-number@10.15.1.12;user=phone><sip:a-number@10.15.1.12;user=phone>;tag=SDkbo9901-42090
        Call-ID: SDkbo9901-71a1d17456b829b4c422af61de9eee7e-ao32g50
        CSeq: 1 ACK
        Contact: 
<sip:a-number@10.15.1.12:5060;transport=udp><sip:a-number@10.15.1.12:5060;transport=udp>
         *Route: sip:10.15.1.30;lr;ftag=SDkbo9901-42090


The problem: this ACK gets not retransmitted to Asterisk

At first, I thought it was some sanity check but after disabling that I 
realized that it was in the WITHINDLG route.

For the incoming ACK I get in the logs:

Jun  8 11:56:47 tone-0866-fe-2-qa /usr/local/sbin/kamailio[53240]: ALERT: 
<script>: Inside LOOSE route for ACK proto=UDP trans=4194304 
from=sip:00754112601@10.15.1.12;user=phone 
route=sip:10.15.1.30;lr;ftag=SDkbo9901-42090 src_ip=10.15.1.12


And once the ACK is ready to be sent to Asterisk, the Route header has been 
removed and no Record-Route has been added so it fails.

Jun  8 11:56:44 tone-0866-fe-2-qa /usr/local/sbin/kamailio[53238]: INFO: rr 
[rr_mod.c:402]: pv_get_route_uri_f(): No route header present.
Jun  8 11:56:44 tone-0866-fe-2-qa /usr/local/sbin/kamailio[53238]: ALERT: 
<script>: ACK does not match transaction!! proto=UDP trans=4194304 
from=sip:00754112601@10.15.1.12;user=phone route= src_ip=10.15.1.30


My WITHINDLG route looks like this:


# Handle requests within SIP dialogs
route[WITHINDLG] {
    if (has_totag()) {
        # sequential request withing a dialog should
        # take the path determined by record-routing
        if (loose_route()) {
            if (is_method("BYE")) {
                xlog("L_ALERT","Inside LOOSE route\n");
                setflag(FLT_ACC); # do accounting ...
                setflag(FLT_ACCFAILED); # ... even if the transaction fails
            }
            if ( is_method("ACK") ) {
                 xlog("L_ALERT","Inside LOOSE route for ACK proto=$rP trans=$mf 
from=$fu route=$route_uri src_ip=$si \n");
                # ACK is forwarded statelessy
                route(NATMANAGE);
            }
            route(RELAY);
        } else {
            if (is_method("SUBSCRIBE") && uri == myself) {
                # in-dialog subscribe requests
                route(PRESENCE);
                exit;
            }
            if ( is_method("ACK") ) {
                if ( t_check_trans() ) {
                    # no loose-route, but stateful ACK;
                    # must be an ACK after a 487
                    # or e.g. 404 from upstream server
                    t_relay();
                    exit;
                } else {
                    # ACK without matching transaction ... ignore and discard
                    xlog("L_ALERT","ACK does not match transaction!! proto=$rP 
trans=$mf from=$fu route=$route_uri src_ip=$si \n");
                        exit;
                }
            }
            sl_send_reply("404","Not here");
        }
        exit;
    }
}


Thanks for reading this ☺ Any idea about how to validate the transaction? 
t_check_trans is not being validated…

Cheers, Francisco.




_______________________________________________

SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list

sr-users@lists.sip-router.org<mailto:sr-users@lists.sip-router.org>

http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users



--

Daniel-Constantin Mierla

http://www.asipto.com - http://www.kamailio.org

http://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda
_______________________________________________
SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list
sr-users@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users

Reply via email to