Comments (34)
No hurry for me - we're covered by the server side fix.
Just wanted to create a ticket regarding this, so no more people would need to scratch their heads about the same thing.
from jssip.
Please print the initial INVITE, 100, 180/183, 200, ACK messages and then the received BYE.
from jssip.
Here you go!
2024-01-17 16:28:14 +0100 : 192.168.75.141:60278 -> 192.168.23.184:443
INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/WSS e2ecvh8aqqb7.invalid;branch=z9hG4bK3017171
Max-Forwards: 69
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=bhkk93kg21
Call-ID: 5hpl8bbtoq2hhhfgcn2k
CSeq: 3488 INVITE
Authorization: Digest algorithm=MD5, username="1705508839:[email protected]", realm="domain.com", nonce="...", uri="sip:[email protected]", response="..."
P-Preferred-Identity: sip:[email protected]
Contact: <sip:[email protected];gr=urn:uuid:9147fcf9-4eda-4259-8997-55f65ef7c97b>
Content-Type: application/sdp
Session-Expires: 3600;refresher=uac
Allow: INVITE,ACK,CANCEL,BYE,UPDATE,MESSAGE,OPTIONS,REFER,INFO,NOTIFY
Supported: timer,gruu,ice,replaces,outbound
User-Agent: JsSIP 3.10.1
Content-Length: 1956
<removed SDP>
2024-01-17 16:28:14 +0100 : 192.168.23.184:443 -> 192.168.75.141:60278
SIP/2.0 100 trying -- your call is important to us
Via: SIP/2.0/WSS e2ecvh8aqqb7.invalid;branch=z9hG4bK3017171;rport=60278;received=192.168.75.141
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=bhkk93kg21
Call-ID: 5hpl8bbtoq2hhhfgcn2k
CSeq: 3488 INVITE
Content-Length: 0
2024-01-17 16:28:16 +0100 : 192.168.23.184:443 -> 192.168.75.141:60278
SIP/2.0 180 Ringing
Via: SIP/2.0/WSS e2ecvh8aqqb7.invalid;rport=60278;received=192.168.75.141;branch=z9hG4bK3017171
Record-Route: <sip:192.168.23.179;lr>
Record-Route: <sip:192.168.23.184;r2=on;lr;ftag=bhkk93kg21>
Record-Route: <sip:192.168.23.184:443;transport=ws;r2=on;lr;ftag=bhkk93kg21>
From: <sip:[email protected]>;tag=bhkk93kg21
To: <sip:[email protected]>;tag=as09dc2c45
Call-ID: 5hpl8bbtoq2hhhfgcn2k
CSeq: 3488 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE, PRACK, UPDATE
Supported: timer, 100rel
Session-Expires: 3600;refresher=uac
Contact: <sip:[email protected]:5060>
Require: timer
Content-Length: 0
2024-01-17 16:28:17 +0100 : 192.168.23.184:443 -> 192.168.75.141:60278
SIP/2.0 200 OK
Via: SIP/2.0/WSS e2ecvh8aqqb7.invalid;rport=60278;received=192.168.75.141;branch=z9hG4bK3017171
Record-Route: <sip:192.168.23.179;lr>
Record-Route: <sip:192.168.23.184;r2=on;lr;ftag=bhkk93kg21>
Record-Route: <sip:192.168.23.184:443;transport=ws;r2=on;lr;ftag=bhkk93kg21>
From: <sip:[email protected]>;tag=bhkk93kg21
To: <sip:[email protected]>;tag=as09dc2c45
Call-ID: 5hpl8bbtoq2hhhfgcn2k
CSeq: 3488 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE, PRACK, UPDATE
Supported: timer, 100rel
Session-Expires: 3600;refresher=uac
Contact: <sip:[email protected]:5060>
Require: timer
Content-Type: application/sdp
Content-Length: 647
<removed SDP>
2024-01-17 16:28:17 +0100 : 192.168.75.141:60278 -> 192.168.23.184:443
ACK sip:[email protected]:5060 SIP/2.0
Route: <sip:192.168.23.184:443;transport=ws;r2=on;lr;ftag=bhkk93kg21>
Route: <sip:192.168.23.184;r2=on;lr;ftag=bhkk93kg21>
Route: <sip:192.168.23.179;lr>
Via: SIP/2.0/WSS e2ecvh8aqqb7.invalid;branch=z9hG4bK7058213
Max-Forwards: 69
To: <sip:[email protected]>;tag=as09dc2c45
From: <sip:[email protected]>;tag=bhkk93kg21
Call-ID: 5hpl8bbtoq2hhhfgcn2k
CSeq: 3488 ACK
Allow: INVITE,ACK,CANCEL,BYE,UPDATE,MESSAGE,OPTIONS,REFER,INFO,NOTIFY
Supported: outbound
User-Agent: JsSIP 3.10.1
Content-Length: 0
2024-01-17 16:28:21 +0100 : 192.168.23.184:443 -> 192.168.75.141:60278
BYE sip:[email protected];gr=urn:uuid:9147fcf9-4eda-4259-8997-55f65ef7c97b SIP/2.0
Via: SIP/2.0/WSS 192.168.23.184:443;branch=z9hG4bK819d.79edfb897b40652e26f39143ec35b1ce.0
Via: SIP/2.0/UDP 192.168.23.179;rport=5060;branch=z9hG4bK819d.363edda7249aa41e91730a76c91ceb7f.0
Via: SIP/2.0/UDP 192.168.23.188:5060;rport=5060;branch=z9hG4bK1652c731
Max-Forwards: 68
From: <sip:[email protected]>;tag=as09dc2c45
To: <sip:[email protected]>;tag=bhkk93kg21
Call-ID: 5hpl8bbtoq2hhhfgcn2k
CSeq: 102 BYE
Content-Length: 0
2024-01-17 16:28:21 +0100 : 192.168.75.141:60278 -> 192.168.23.184:443
SIP/2.0 404 Not Found
Via: SIP/2.0/WSS 192.168.23.184:443;branch=z9hG4bK819d.79edfb897b40652e26f39143ec35b1ce.0
Via: SIP/2.0/UDP 192.168.23.179;rport=5060;branch=z9hG4bK819d.363edda7249aa41e91730a76c91ceb7f.0
Via: SIP/2.0/UDP 192.168.23.188:5060;rport=5060;branch=z9hG4bK1652c731
To: <sip:[email protected]>;tag=bhkk93kg21
From: <sip:[email protected]>;tag=as09dc2c45
Call-ID: 5hpl8bbtoq2hhhfgcn2k
CSeq: 102 BYE
Content-Length: 0
from jssip.
You are not explicitly passing any "contact" to new UA, right? So it looks like if JsSIP takes the identity uri, converts it to low case and use it as Contact header. That's perfectly fine since it can use whatever it wants. Problem is that the incoming BYE is rejected with 404 despite its RURI matches the Contact URI of the initial INVITE. My guess is that JsSIP stores internally the contact header without converting it to low case, then it converts it to low case when sending the INVITE, and later when the BYE arrives JsSIP tries to match the RURI (which is all low case to match the INVITE'/s Contact) using its internally stored identity URI which is not in low case.
@jmillan thoughts?
from jssip.
You're correct. I'm not specifying the contact directly.
Afaik, I wasn't aware that that was an option.
It seems like some other people also had the same struggle, so would be nice with a fix and/or at least - a clarification :)
from jssip.
I tested using contact_uri too with the original non-lowercased value, and it seems to end with the same result.
from jssip.
@mtryfoss, can you please share the REGISTER request and response? I'm wondering if the registrar server is the one lowercasing the URI in the pub gruu.
from jssip.
The user-part of To and From is in lower case, while username in Authorization header is like it should be.
REGISTER sip:domain.com SIP/2.0
Via: SIP/2.0/WSS tkb9vrejfuua.invalid;branch=z9hG4bK9724461
Max-Forwards: 69
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=4l3k4ii8o1
Call-ID: rdpm76h7q47lujq80n9dup
CSeq: 2 REGISTER
Authorization: Digest algorithm=MD5, username="1705577130:[email protected]", realm="domain.com", nonce="...", uri="sip:domain.com", response="..."
Contact: <sip:[email protected];transport=ws>;+sip.ice;reg-id=1;+sip.instance="<urn:uuid:44e0581c-0d2a-4a7f-aca5-bfdcddd9f742>";expires=300
Expires: 300
Allow: INVITE,ACK,CANCEL,BYE,UPDATE,MESSAGE,OPTIONS,REFER,INFO,NOTIFY
Supported: path,gruu,outbound
User-Agent: JsSIP 3.10.1
Content-Length: 0
SIP/2.0 200 OK
Via: SIP/2.0/WSS tkb9vrejfuua.invalid;rport=49556;received=192.168.75.141;branch=z9hG4bK1484306
To: <sip:[email protected]>;tag=78322ec717f7a5b13edafae546c3bb10.49460000
From: <sip:[email protected]>;tag=kp3a0fcvvq
Call-ID: rdpm76h7q47lujq80n9dup
CSeq: 2 REGISTER
Contact: <sip:[email protected];transport=ws>;expires=300;pub-gruu="sip:[email protected];gr=urn:uuid:44e0581c-0d2a-4a7f-aca5-bfdcddd9f742";temp-gruu="sip:[email protected];gr";+sip.instance="<urn:uuid:44e0581c-0d2a-4a7f-aca5-bfdcddd9f742>";reg-id=1
Supported: outbound
Require: outbound
Content-Length: 0
I'm using save() in the Kamailio registrar module with an explicit URI based on the Authorization header, which is the correct string (non-lower case).
However, I see the user-part of the Kamailio-registration appears to be saved in all lower.
Checking the docs, I see this one:
3.10. case_sensitive (integer)
If set to 1 then AOR comparison and also storing will be case sensitive, if set to 0 then AOR comparison and storing will be case insensitive. This is recommended. This parameter can be modified via Kamailio config framework.
Default value is 0.
Changing that to 1, stores the AOR correct.
Now the INVITE is sent with the correct user in the Contact (and From) too:
Contact: <sip:1jjIz6hYXjgzOTLEyhBEeJoCnYV@....
And the BYE is accepted, even after I removed the toLowerCase() in the settings for the client.
I'm part of the Kamailio team too, but was not aware of this setting. I'll bring it up to maybe change the default.
All in all, a quite confusing case.
The question is then, would it cause any trouble for JsSIP to handle this situation for others which may not be able to fix it server side?
from jssip.
Despite what kamailio registrar does, the fact here is that:
- JsSIP sets this Contact in its INVITE:
Contact: <sip:[email protected];gr=urn:uuid:9147fcf9-4eda-4259-8997-55f65ef7c97b>
- Then JsSIP receives a BYE with RURI
sip:[email protected];gr=urn:uuid:9147fcf9-4eda-4259-8997-55f65ef7c97b
which perfectly matches the Contact URI that JsSIP used in the INVITE. - But JsSIP cannot match the BYE and replies with 404. So something is wrong in JsSIP.
from jssip.
BTW I fail to see how the Authorization header can affect this problem, it's supposed to be the credentials for the client to get registered and make calls. It should not directly affect the generated Contact URIs. Also I don't understand the problem you said in the REGISTER flow. JsSIP sets a low case uri in the REGISTER and Kamailio honors it (in low case) in the 200 to the REGISTER.
from jssip.
I originally included the signalling with my client-side workaround in place, so it registers with all-lower. Edited the post to what I can see after altering behaviour in both ends.
To conclude I think we can say:
- the default settings in Kamailio is not honouring the RFC for the REGISTER-handling.
- JsSIP is not handling this INVITE/BYE scenario isolated (it should accept the URI in a BYE that has been used as Contact in the INVITE).
from jssip.
Can you please show the changes in the edited REGISTER flow with that kamailio setting set to default value? I cannot see the difference (note: I'm in mobile with super low availability for some days).
from jssip.
This should be before the client workaround, and with default setting in Kamailio.
REGISTER sip:domain.com SIP/2.0
Via: SIP/2.0/WSS q5q96qlrkps3.invalid;branch=z9hG4bK1767564
Max-Forwards: 69
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=de0133hugt
Call-ID: igh7bgvafcobtbp26jsgs9
CSeq: 2 REGISTER
Authorization: Digest algorithm=MD5, username="1705508948:[email protected]", realm="domain.com", nonce="...", uri="sip:domain.com", response="..."
Contact: <sip:[email protected];transport=ws>;+sip.ice;reg-id=1;+sip.instance="<urn:uuid:d1996bf3-326c-4d2d-9f7b-f91a017f123f>";expires=300
Expires: 300
Allow: INVITE,ACK,CANCEL,BYE,UPDATE,MESSAGE,OPTIONS,REFER,INFO,NOTIFY
Supported: path,gruu,outbound
User-Agent: JsSIP 3.10.1
Content-Length: 0
SIP/2.0 200 OK
Via: SIP/2.0/WSS q5q96qlrkps3.invalid;rport=61044;received=192.168.54.193;branch=z9hG4bK1767564
To: <sip:[email protected]>;tag=78322ec717f7a5b13edafae546c3bb10.b2010000
From: <sip:[email protected]>;tag=de0133hugt
Call-ID: igh7bgvafcobtbp26jsgs9
CSeq: 2 REGISTER
Contact: <sip:[email protected];transport=ws>;expires=300;pub-gruu="sip:[email protected];gr=urn:uuid:d1996bf3-326c-4d2d-9f7b-f91a017f123f";temp-gruu="sip:[email protected];gr";+sip.instance="<urn:uuid:d1996bf3-326c-4d2d-9f7b-f91a017f123f>";reg-id=1
Supported: outbound
Require: outbound
Content-Length: 0
Returned contact: pub-gruu="sip:[email protected]
from jssip.
Returned contact: pub-gruu="sip:[email protected]
Sorry, and what's the problem or unexpected thing with this returned contact? Why should it be different? I insi that the fact that it doesn't match the username in the Authorization header is irrelevant. Do I miss something? (Sorry I'm on vacation)
from jssip.
JsSIP is not handling this INVITE/BYE scenario isolated (it should accept the URI in a BYE that has been used as Contact in the INVITE).
I don't think JsSIP should store all temp
and and pub
GRUU's that have been used during a session. The spec clear says that the GRUU generation must adhere to the following:
https://www.rfc-editor.org/rfc/rfc5627#section-5.4
Every GRUU is associated with a single AOR
and a single instance ID.
sip:[email protected];gr=urn:uuid:d1996bf3-326c-4d2d-9f7b-f91a017f123f
is different from
sip:[email protected];gr=urn:uuid:d1996bf3-326c-4d2d-9f7b-f91a017f123f
, meaning that the GRUU cannot convert the case of the AOR it contains.
from jssip.
@jmillan, despite the kamailio gruu low case stuff, do you see the problem in the REGISTER + INVITE + incoming BYE flow? Because I don't so I don't really understand why JsSIP fails to match the incoming BYE. The RURI of the BYE matches the Contact in the 200 of the REGUSTER. So what's the problem?
from jssip.
Seems like JsSIP is somehow falling back to matching this against the configured value (settings), and not what it use for the INVITE?
from jssip.
And what is the configured value in settings?
from jssip.
Sorry, my bad. It's been so much back and forth here :)
That was my previous presumption since I didn't notice it was actually the REGISTER-response causing it to use in lower case.
It will not match against the settings, since they could be in both upper and lower while the contact is in lower.
from jssip.
But I insist something must be wrong in JsSIP side. Can you show the settings you pass to new JsSIP.UA()?
from jssip.
At first we only used:
uri: '[email protected]',
authorization_user: '1705588985:[email protected]',
but then we also tried specifying contact_uri explicitely:
contact_uri: 'sip:[email protected]',
Same effect.
from jssip.
At first we only used:
uri: '[email protected]'
So here the bug because the uri is given with low and upper chars but the JsSIP generated Contact URI is in low case so later it doesn't match the RURI of the incoming BYE (which is correct) because it's in low case. Yes, here the bug. Somewhere in JsSIP we are converting the given settings uri to low case when we generate the REGISTER and the INVITE, but we keep it in upper+low case in memory and use it to match incoming requests. That's the bug.
from jssip.
Nop,
-
JsSIP sends a REGISTER with TO URI:
sip:[email protected]
-
REGISTER response comes with pub_gruu:
sip:[email protected];gr=urn:uuid:44e0581c-0d2a-4a7f-aca5-bfdcddd9f742
NOTE lowercase, this is against the spec, it does not represent the AoR -
JsSIP uses the pub_gruu as the Contact in outgoing requests.
-
JsSIP receives a request (BYE) with the pub_gruu in the RURI, which does not point to user AoR.
- We don't process a request that does not point to us according to URI equality rules.
In summary, the issue is in the server lowercasing the AoR in the pub_gruu, which makes it identify a different AoR.
from jssip.
JsSIP sends a REGISTER with TO URI: sip:[email protected]
Where do you see that in messages above? I see this instead in the REGISTER sent by JsSIP:
Contact: sip:[email protected];transport=ws;+sip.ice;reg-id=1;+sip.instance="urn:uuid:d1996bf3-326c-4d2d-9f7b-f91a017f123f";expires=300
All in low case. So it should match and accept a BYE with same RURI in low case. But it doesn't.
from jssip.
Where do you see that in messages above?
here: #844 (comment)
from jssip.
Where do you see that in messages above?
here: #844 (comment)
The contact in that REGISTER is:
Contact: sip:[email protected];transport=ws;+sip.ice;reg-id=1;+sip.instance="urn:uuid:44e0581c-0d2a-4a7f-aca5-bfdcddd9f742";expires=300
Where do you see upper chars there?
from jssip.
Where do you see upper chars there?
That is the Contact generated by us in the REGISTER. I did not mention that in my comment here #844 (comment)
from jssip.
JsSIP sends a REGISTER with TO URI: sip:[email protected]
REGISTER response comes with pub_gruu: sip:[email protected];gr=urn:uuid:44e0581c-0d2a-4a7f-aca5-bfdcddd9f742 NOTE lowercase, this is against the spec, it does not represent the AoR
This is your comment but still I don't see any evidence that JsSIP sends REGISTER with upper case chars in the Contact header. I just see it in your comment, nowhere else. I may be wrong.
from jssip.
This is your comment but still I don't see any evidence that JsSIP sends REGISTER with upper case chars in the Contact header. I just see it in your comment, nowhere else. I may be wrong.
Not the in the Contact header, but in the To header. The registrar extracts the AoR from the To header field and creates the GRUU out of it, which adds to the Contact header in the response. As part of the GRUU creation, the registrar lower cases the AoR, which I claim to be the bug.
from jssip.
I would absolutely say it's a non-optimal behaviour/bug in the way Kamailio works without modified settings.
Regardless of that, wouldn't it be a good idea to handle this in JsSIP so it at least accepts a BYE to a URI matching a contact in an INVITE sent by the same client?
Maybe log a notice about it in the REGISTER process, if the returned contact no longer match the expected value?
It was more or less pure luck I found the cause relatively quick.
Looking at the call isolated, there's literally no reason at all it shouldn't work.
from jssip.
Not the in the Contact header, but in the To header. The registrar extracts the AoR from the To header field and creates the GRUU out of it, which adds to the Contact header in the response. As part of the GRUU creation, the registrar lower cases the AoR, which I claim to be the bug.
The pub-gruu in the REGISTER 200 is clearly in low case, and JsSIP uses that pub-gruu in low case in the Contact of the INVITE so it honors it. So it should match the BYE since its RURI perfectly matches the Contact URI that JsSIP told to the callee. But is doesn't so hence the bug in JsSIP.
The pub-gruu is chosen/decided by the registrar server. JsSIP should not expect any specific URI. That's why the pub-gruu is indicated in the REGISTER 200.
from jssip.
Section 5.4 of RGC 5627 clearly says:
This specification does not mandate a particular mechanism for
construction of the GRUU. Example algorithms for public and
temporary GRUUs that work well are given in Appendix A. However, in
addition to the properties described in Section 3.1, a GRUU
constructed by a registrar MUST exhibit the following properties:
o The domain part of the URI is an IP address present on the public
Internet, or, if it is a hostname, the resolution procedures of
RFC 3263 [2], once applied, result in an IP address on the public
Internet.
o When a request is sent to the GRUU, it routes to a proxy that can
access the registration data generated by the registrar. Such a
proxy is called an authoritative proxy, defined in RFC 5626 [14].
Appendix A says:
pendix A. Example GRUU Construction Algorithms
The mechanism for constructing a GRUU is not subject to
specification. This appendix provides an example that can be used by
a registrar to construct a public and a temporary GRUU. Of course,
others are permitted, as long as they meet the constraints defined
for a GRUU.
A.1. Public GRUU
The most basic approach for constructing a public GRUU is to take the
AOR and place the actual value of the instance ID into the contents
of the "gr" URI parameter.
In other words: the registrar can decide how the entire pub gruu looks. So this is only a bug in JsSIP despite the low case stuff of kamailio.
from jssip.
I missread the spec and interpreted that the AoR should be included too.
I don't have an ETA myself for this fix as for now, as I have my hands at this momemt.
from jssip.
Related Issues (20)
- Change type of request in OutgoingRTCSessionEvent to OutgoingRequest HOT 2
- 'hold' and 'unhold' event listener are not triggered for the remotes hold/unhold events HOT 1
- UA.call or any other method not working as expected with VueJS HOT 1
- Allow set JSSIP.UA extra_headers in runtime HOT 2
- resetLocalMedia is declared but not implemented HOT 1
- Make a call with error 488 Not Acceptable Here How to fix it HOT 1
- JsSIP Logger Override Functionality Not Working As Expected in v3.7.7 HOT 1
- UnMute Call HOT 2
- How not to get microphone permission HOT 1
- For SIP server Account Register Working? HOT 2
- Abnormal session cancellation method under race condition
- Type definition errors in 3.10.0 HOT 1
- Error when getting video track status on Firefox
- Play audio or tone to remote user. HOT 2
- The new JsSIP.UA(configuration).call method does not return the status after execution
- import JsSIP from "jssip"; 打印JsSIP undefined HOT 2
- Error 'setLocalDescription' on Chrome HOT 1
- Incorrect SDP a=sendrecv in firefox HOT 7
- I want to send and Receive message using JSSIP
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jssip.