### Description
Kamailio with TOPOS enabled acts as a proxy between SIP client and SBC. When client sends "180 Ringing" without Contact header - kamailio does not forward it to SBC. If Contact header exists in "180 Ringing" - all works as expected.
### Troubleshooting
#### Reproduction
Load and configure topos module Make call with "180 Ringing" without Contact header - kamailio will not forward it.
#### Log Messages
``` ERROR: topos [tps_storage.c:340]: tps_storage_link_msg(): bad sip message or missing Contact hdr ```
#### SIP Traffic
``` SIP/2.0 180 Ringing Via: SIP/2.0/TLS 1.2.3.4:5061;branch=z9hG4bKef45.8c75f0bae8a59dfaec6ff533ff0f3b2d.0 From: sip:1111@1.2.3.4:5061;tag=02000879948559 To: sip:2.2.2.2@5.6.7.8:5061;transport=tls;user=phone;tag=SDbsq8499-y2pMOVV Call-ID: apdW7374315131g0bcGhEfDjFof CSeq: 988207425 INVITE User-Agent: agent Supported: replaces, outbound Content-Length: 0 ```
### Additional Information
* **Kamailio Version** - output of `kamailio -v`
``` version: kamailio 5.1.6 (x86_64/linux) flags: STATS: Off, USE_TCP, USE_TLS, USE_SCTP, TLS_HOOKS, DISABLE_NAGLE, USE_MCAST, DNS_IP_HACK, SHM_MEM, SHM_MMAP, PKG_MALLOC, Q_MALLOC, F_MALLOC, TLSF_MALLOC, DBG_SR_MEMORY, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE, USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLACKLIST, HAVE_RESOLV_RES ADAPTIVE_WAIT_LOOPS=1024, MAX_RECV_BUFFER_SIZE 262144, MAX_LISTEN 16, MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 8MB poll method support: poll, epoll_lt, epoll_et, sigio_rt, select ```
* **Operating System**:
``` Red Hat Enterprise Linux Server 7.3
3.10.0-514.el7.x86_64 #1 SMP Wed Oct 19 11:24:13 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux ```
You are right, according to the RFC the Contact Header is optional in 1xx: https://tools.ietf.org/html/rfc3261#section-20.1 The RFC says as well that it SHOULD be included, but it is not a MUST.
Can you try with master branch or using the patch from the commit referenced above?
Hi Daniel. I have try. Now "180 ringing" is sending to SBC by kamailio. But kamailio adds "Contact" header to forwarded message. Can you look, please?
Linphone to kamailio ``` SIP/2.0 180 Ringing Via: SIP/2.0/TLS 1.2.3.4:5061;branch=z9hG4bK460b.6e02acd9418a5aae97a9d5f79aeffc53.0 From: sip:1111@1.2.3.4:5061;tag=14003117305244 To: sip:2222@5.6.7.8:5061;transport=tls;user=phone;tag=S7nIf9Z Call-ID: 0KaR2073911201UQbcGhEfDeMek CSeq: 669313 INVITE User-Agent: LinphoneAndroid/4.0.1 (belle-sip/1.6.3) Supported: replaces, outbound Content-Length: 0 ```
kamailio to SBC ``` SIP/2.0 180 Ringing From: sip:1111@1.2.3.4;tag=14003117305244 To: sip:2222@5.6.7.8;tag=S7nIf9Z Call-ID: 0KaR2073911201UQbcGhEfDeMek CSeq: 669313 INVITE Content-Length: 0 Via: SIP/2.0/UDP 1.2.3.4:5060;rport=5060;received=10.56.63.10;branch=z9hG4bK00000005167007511555 Contact: sip:atpsh-5bf3d61d-2547-1@10.56.42.33 Record-Route: sip:KITS1.MSS.LIFE.COM:5060;transport=UDP;lr
```
Is this causing a problem?
The kamailio + topos is not adding Record-Route headers, so Contact would be required for routing if some UA wants to send a some request within early dialog.
I agree with you. But now I see that after ``` SIP/2.0 180 Ringing From: sip:1111@1.2.3.4;tag=14003117305244 To: sip:2222@5.6.7.8;tag=S7nIf9Z Call-ID: 0KaR2073911201UQbcGhEfDeMek CSeq: 669313 INVITE Content-Length: 0 Via: SIP/2.0/UDP 1.2.3.4:5060;rport=5060;received=10.56.63.10;branch=z9hG4bK00000005167007511555 Contact: sip:atpsh-5bf3d61d-2547-1@10.56.42.33 Record-Route: sip:KITS1.MSS.LIFE.COM:5060;transport=UDP;lr ``` I getting BYE from SBC as ``` BYE sip:atpsh-5bf4031e-3f23-1@10.56.42.33 SIP/2.0 From: sip:1111@1.2.3.4;tag=14003117305244 To: sip:2222@5.6.7.8;tag=S7nIf9Z Max-Forwards: 70 Via: SIP/2.0/UDP KITS1.MSS.LIFE.COM:5060;branch=z9hG4bK00000016862453278154 Call-ID: 9afY9565014201gpbcGhEfCmGjd@KITS1.MSS.LIFE.COM CSeq: 670210 BYE Reason: Q.850;cause=16 Content-Length: 0 ``` But kamailio sends to Linphone BYE with second route in r-uri ``` BYE sip:5.6.7.8:5081;transport=tcp;r2=on;lr;ftag=02003459426351;did=96e.f6f2;vsf=AAAAAAoLCAsBCQcKAnVzehQYeHoeYn1jHxpoCWcFCmN4Oj5lcj1waG9uZQ--;vst=AAAAAAoLAQ4DAA4DAHlnYg4HGh59BRloCWcFCmN4Oj5eB04VGlIeDW9uZQ--;nat=yes SIP/2.0 From: sip:1111@1.2.3.4;tag=14003117305244 To: sip:2222@5.6.7.8;tag=S7nIf9Z Max-Forwards: 70 Via: SIP/2.0/UDP KITS1.MSS.LIFE.COM:5060;branch=z9hG4bK00000016862453278154 Call-ID: 9afY9565014201gpbcGhEfCmGjd@KITS1.MSS.LIFE.COM CSeq: 670210 BYE Reason: Q.850;cause=16 Content-Length: 0 ``` How I can got r-uri from original INVITE in this case?
Any reason for sending BYE before 200ok? It should be a CANCEL if the call initiation is wanted to be stopped. BYE can be sent also in early dialog phase (to close a single branch of an ongoing call setup), but looks like not the case here.
I can add a patch to skip adding the Contact, just that the scenario above is not clear.
Pushed also the commit to skip adding contact in 1xx if the header is not in the incoming response.
Thank you Daniel. I think skip adding the Contact is not needed.
I have Ericsson STP, and it sends BYE even at early dialog phase.
But I think I can change this behavior by myself.
Thank you for fixing issue with "180 Ringing" without Contact.
As I said, the BYE in early phase is ok, when willing to end a specific branch, but typically after 183 which establishes a connected brach for early media. Maybe the BYE was sent in this case because of the Contact in 180, thinking that was an established branch. That was the reason I decided to skip adding the Contact in the response sent out if the incoming one does not have one.
Maybe you have the chance to test and see if the BYE is still sent when no Contact is in 180.
Just trued with latest commit: ``` SIP/2.0 180 Ringing From: sip:1111@1.2.3.4;tag=08001964526856 To: sip:sip:2222@5.6.7.8;tag=vy~HzZJ Call-ID: vqeU544121321136bcGhEfCjEbh CSeq: 672321 INVITE Content-Length: 0 Via: SIP/2.0/UDP KITS1.MSS.LIFE.COM:5060;rport=5060;received=10.56.63.10;branch=z9hG4bK00000017483123160717 Record-Route: sip:KITS1.MSS.LIFE.COM:5060;transport=UDP;lr ```
Ericsson still terminate with a BYE
``` BYE sip:sip:2222@5.6.7.8 SIP/2.0 From: sip:1111@1.2.3.4;tag=08001964526856 To: sip:sip:2222@5.6.7.8;tag=vy~HzZJ Max-Forwards: 70 Via: SIP/2.0/UDP KITS1.MSS.LIFE.COM:5060;branch=z9hG4bK00000017580316458612 Call-ID: vqeU544121321136bcGhEfCjEbh CSeq: 672322 BYE Reason: Q.850;cause=16 Content-Length: 0 ```
And now kamailio responce to BYE from A side with "404 not here" ``` SIP/2.0 404 Not here From: sip:1111@1.2.3.4;tag=08001964526856 To: sip:sip:2222@5.6.7.8;tag=vy~HzZJ Via: SIP/2.0/UDP KITS1.MSS.LIFE.COM:5060;branch=z9hG4bK00000017580316458612;rport=5060;received=10.56.63.10 Call-ID: vqeU544121321136bcGhEfCjEbh CSeq: 672322 BYE Content-Length: 0 ```
Seems it fails in check "if (loose_route())"
Closed #1720.
The same (similar) result should be when not using topos, because the other side didn't give any contact where to forward the BYE.
So in this case you have to route the BYE like you did the INVITE. Eventually store in an htable where you sent the INVITE (using call-id as a key) and forward the BYE there. Something like: if the ruri of BYE is myself and there is an item in htable, then route the BYE there.
I am going to close this issue, the behavior is like expected without topos. If there is more that you want to discuss about routing a BYE when no Contact was provided (with or without topos), the best is to use sr-users mailing list.
@miconda Please check latest commit. It brakes 180 and 183 responses with Contact header ``` /* keep contact without updates for redirect responses sent out */ ** if(msg->first_line.u.reply.statuscode<300 ** || msg->first_line.u.reply.statuscode>=400) { contact_keep = 1; } if(contact_keep==0 && msg->first_line.u.reply.statuscode>100 && msg->first_line.u.reply.statuscode<200 && msg->contact==NULL) { contact_keep = 1; } if(contact_keep==0) { ``` Expression marked with ** evaluates for 180 and 183 before your expression and set contact_keep = 1 so next expression will not be evaluated.
Thank you.
@miconda I think correct way will be: ``` tps_remove_headers(msg, HDR_RECORDROUTE_T);
if(msg->first_line.u.reply.statuscode>100 && msg->first_line.u.reply.statuscode<200 && msg->contact==NULL) { contact_keep = 1; }
/* keep contact without updates for redirect responses sent out */ if(contact_keep==0 && (msg->first_line.u.reply.statuscode<300 || msg->first_line.u.reply.statuscode>=400)) { tps_remove_headers(msg, HDR_CONTACT_T);
if(direction==TPS_DIR_DOWNSTREAM) { tps_reinsert_contact(msg, &stsd, &stsd.as_contact); } else { tps_reinsert_contact(msg, &stsd, &stsd.bs_contact); } }
tps_reappend_rr(msg, &btsd, &btsd.x_rr); ```
Indeed, the previous commit broke matching 3xx responses. I pushed a patch for it, see above, can you test and confirm if it works or not?
Thank you Daniel. Now it works as expected.
Did you will backport this change into kamailio 5.1?
@miconda
I'm sorry to write in this already closed issue, but I have a problem related to the fixes implemented to solve this problem. In particular I would like to ask you why, in case of TOPOS module enabled, the Contact is a mandatory header for 183 messages as implemented in commit 416d79b462986317f2c3a3ed8aa30a502d116095.
From RFC the Contact header is optional for all the 1xx reply messages.
I don't have any issue when I receive 183 messages without Contact header if TOPOS module is disabled. When I enabled it, instead, I fall in the mentioned check.
Thanks
We are seeing the same issue here with 183 replies not getting forwarded if theyu lack a Contact header. Is there a reason this is explicitly excluded from the 1xx replies:
``` if(msg->first_line.u.reply.statuscode>=100 && msg->first_line.u.reply.statuscode<200 && msg->first_line.u.reply.statuscode!=183) { /* provisional response with no mandatory contact header */ return 0; } ```
Thanks
I pushed the commit 785326cdfbee849a8436e7c07003ff0539d259cd to allow 183 without contact. An 183 creates an early session, can be followed by PRACK, which needs the contact, I am not sure now if it is mandatory, but I have seen 183 without contact, so it should be fine to accept it without contact. It will be backported till the next point release.