### Description
I noticed an issue regarding loose_route() when using Topos module.
My architecture is the following:
``` Client (behind NAT or not) ------> Kamailio (Access SBC) -----------> Kamailio (Interconnect SBC) -----------> Carrier
```
Kamailio Access SBC is listening on 2 interfaces:
``` Public interface : udp:A.A.A.A:5060 Core interface : udp:B.B.B.B:5060
```
Kamailio Interconnect SBC is listening on 2 interfaces:
``` Core interface : udp:C.C.C.C:5060 Carrier-side interface : udp:D.D.D.D:5060
```
TOPOS is configured only on second kamailio box (Interconnect SBC). Record routing is used on both kamailios.
TOPOS module is configured as follows:
``` modparam("ndb_redis", "server", "name=srv1;addr=127.0.0.1;port=6379") modparam("topos_redis", "serverid", "srv1")
modparam("topos", "storage", "redis") modparam("topos", "contact_mode", 1) modparam("topos", "cparam_name", "id") modparam("topos", "rr_update", 1)
```
RR module is configured as follows:
``` modparam("rr", "enable_full_lr", 1) modparam("rr", "append_fromtag", 1) modparam("rr", "enable_double_rr", 1)
```
For an incomoing INVITE (direction: client to carrier) all is fine and topos can strip headers on bleg and insert the cookie on bleg contact as a param.
When Callee sends a BYE or re-INVITE, topos inserts route headers in aleg as shown in the next trace: (BYE as received from the carrier on the carrier-side interface D.D.D.D)
``` BYE sip:D.D.D.D:5060 SIP/2.0 Via: SIP/2.0/UDP x.x.x.x:5060;branch=z9hG4bKrdhsvc001omkvssqvfk0sd0185mt1.1 From: sip:+33123456789@my-carrier-domain;transport=UDP;user=phone;tag=SD69ao497-1472568650-1635329820043 To: sip:+33987654321@my-own-domain;transport=UDP;user=phone;tag=3ab10616 Call-ID: NjZjMDgyMGMxNzdkN2FhYmJlYzQyYjA5YWIzZThmZmI. CSeq: 547381883 BYE Max-Forwards: 64 Content-Length: 0 Route: sip:D.D.D.D;r2=on;lr=on;ftag=3ab10616,sip:C.C.C.C;r2=on;lr=on;ftag=3ab10616 Route: sip:B.B.B.B;r2=on;lr=on;ftag=3ab10616;dlg_id=426.26c2,sip:A.A.A.A;r2=on;lr=on;ftag=3ab10616;dlg_id=426.26c2 P-SR-XUID: atpsh-617925e5-82a5-1
```
Topos on the kamailio interconnect handles the BYE/re-INVITE and forward it to the second interface C.C.C.C as shown in the following trace:
``` BYE sip:A.A.A.A;r2=on;lr=on;ftag=3ab10616;dlg_id=426.26c2 SIP/2.0 Via: SIP/2.0/UDP 185.164.213.110;branch=z9hG4bKbd7.ab692eeb60369aa3a5e07f6b63cc9dd7.0 From: sip:+33123456789@my-carrier-domain;transport=UDP;user=phone;tag=SD69ao497-1472568650-1635329820043 To: sip:+33987654321@my-own-domain;transport=UDP;user=phone;tag=3ab10616 Call-ID: NjZjMDgyMGMxNzdkN2FhYmJlYzQyYjA5YWIzZThmZmI. CSeq: 547381883 BYE Max-Forwards: 63 Content-Length: 0 Route: sip:C.C.C.C;r2=on;lr=on;ftag=3ab10616 Route: sip:B.B.B.B;r2=on;lr=on;ftag=3ab10616;dlg_id=426.26c2 Contact: sip:+33123456789@10.3.60.45;id=atpsh-617925e5-82a5-1
```
When the BYE/re-INVITE request reaches the C.C.C.C interface, it is then forwarded directly to the ruri sip:A.A.A.A.
Or what I expect to receive in C.C.C.C interface is the following :
``` BYE <HERE SHOULD BE THE CALLER CONTACT URI> SIP/2.0 Via: SIP/2.0/UDP 80.10.231.173:5060;branch=z9hG4bKrdhsvc001omkvssqvfk0sd0185mt1.1 From: sip:+33123456789@my-carrier-domain;transport=UDP;user=phone;tag=SD69ao497-1472568650-1635329820043 To: sip:+33987654321@my-own-domain;transport=UDP;user=phone;tag=3ab10616 Call-ID: NjZjMDgyMGMxNzdkN2FhYmJlYzQyYjA5YWIzZThmZmI. CSeq: 547381883 BYE Max-Forwards: 64 Content-Length: 0 Route: sip:D.D.D.D;r2=on;lr=on;ftag=3ab10616 Route: sip:C.C.C.C;r2=on;lr=on;ftag=3ab10616 Route: sip:B.B.B.B;r2=on;lr=on;ftag=3ab10616;dlg_id=426.26c2 Route: sip:A.A.A.A;r2=on;lr=on;ftag=3ab10616;dlg_id=426.26c2 Contact: sip:+33123456789@10.3.60.45;id=atpsh-617925e5-82a5-1
```
I could work around this issue by doing the following :
1. When receiving the BYE/re-INVITE on interface D.D.D.D, I explode the Route headers, delete old route headers and create new ones in order from the result of explode 2. I update the ru with the contact uri which I stored in a htable when the initial INVITE was received
``` # Manage outgoing branches branch_route[MANAGE_BRANCH] { xdbg("new branch [$T_branch_idx] to $ru\n");
# TOPOS FIX if (is_method("INVITE")) { $sht(tpsindlg=>$ci) = $ci; $sht(tpsindlg=>$ci:ft) = $ft; $sht(tpsindlg=>$ci:ct) = $ct; } }
route[WITHINDLG] { if (!has_totag()) return;
# Fix bad Route Headers caused by TOPOS module if ($Ri == "D.D.D.D") { $var(rh0) = $(hdr(Route)[0]{s.select,0,,}); $var(rh1) = $(hdr(Route)[0]{s.select,1,,}); $var(rh2) = $(hdr(Route)[1]{s.select,0,,}); $var(rh3) = $(hdr(Route)[1]{s.select,1,,});
remove_hf_re("^Route$");
append_hf("Route: $var(rh0)\r\n"); append_hf("Route: $var(rh1)\r\n"); append_hf("Route: $var(rh2)\r\n"); append_hf("Route: $var(rh3)\r\n"); }
# sequential request within a dialog should # take the path determined by record-routing if (loose_route()) {
# Fix R-URI caused by TOPOS module if ($Ri == "D.D.D.D") { if ($ci == $sht(tpsindlg=>$ci) && $tt == $sht(tpsindlg=>$ci:ft)) { $ru = $(sht(tpsindlg=>$ci:ct){s.strip,1}{s.striptail,1});
if (is_method("BYE")) { $sht(tpsindlg=>$ci) = $null; $sht(tpsindlg=>$ci:ft) = $null; $sht(tpsindlg=>$ci:ct) = $null; } } }
route(RELAY); 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 route(RELAY); exit; } else { # ACK without matching transaction ... ignore and discard exit; } }
sl_send_reply("404","Not here"); exit; }
```
Could you please tell if this is a normal behavior by TOPOS module or is it a bug?
Thank you.
The BYE should not have R-URI pointing to local Kamailio (D.D.D.D) if you got that BYE content from the Kamailio. If you got it with ngrep from the network, then it should be no Route headers pointing to local Kamailio (D.D.D.D).
This does not look as a topos C code issue, it can be some misconfiguration or broken systems that interact with kamailio.
To sort out what it is, write to sr-users@lists.kamailio.org providing the ngrep output for such call taken on kamailio with topos, using:
``` ngrep -d any -qt -W byline port 5060 ```
Then we can discuss there what might be the causes and if it is a bug in the C code, a corresponding issue can be created here.
Closed #2905.