why we have CSeq: 1 INVITE and CSeq: 2 INVITE
what is for request
Who will give me the correct response
why we have CSeq: 1 INVITE and CSeq: 2 INVITE
what is for request
Who will give me the correct response
some servers like cisco
can invite just CSeq: 1 not need 2
and some servers need 1 and need 2
What is the way to make me distinguish if I need to invite 2 or not
CSeq or Command Sequence contains an integer and a method name. The CSeq number is incremented for each new dialog request and is a traditional sequence number.
Nothing fancy, just a sequence number incremented as you can see with CSEQ 1 INVITE and CSEQ 2 INVITE, if I assume you are receiving two INVITE on the same dialogue then just respond to the last CSEQ, in that case CSEQ 2 INVITE.
Logically, it is just a retransmission, you do not have to answer to both only the last received one.
Related
Trying to determine the correct behavior in this scenario. A SIP B2BUA sends Invite to SBC, the SBC responds with 200 OK but before receiving the ACK the SBC sends a re-Invite to modify SDP, to which the B2BUA responds with 500 Race Condition.
Call flow:
Client B2BUA SBC
| Invite -> | |
| | Invite -> |
| | <- 200 OK |
| <- 200 OK | |
| | |
| | <- re-Invite |
| | 500 Race -> |
| | |
In RFC3261 I can't find any reference that it's necessary to wait for ACK.
In section 14.1 I do see reference:
2. If there is an ongoing INVITE server transaction, the TU MUST
wait until the transaction reaches the confirmed or terminated
state before initiating the new INVITE.
Looking at the INVITE server transaction diagram it appears the 200 OK has moved the server transaction to terminated state but I'm not sure that's the correct context for this scenario.
Must the SBC wait for ACK before sending re-Invite or should the B2BUA accept the re-Invite?
It is normal that you get race condition because B2BUA is trying to handle two INVITE request at the same time, first INVITE needs to properly processed. Inside the same document that you've sent:
Note that a UAC MUST NOT initiate a new INVITE transaction within a
dialog while another INVITE transaction is in progress in either
direction.
1. If there is an ongoing INVITE client transaction, the TU MUST
wait until the transaction reaches the completed or terminated
state before initiating the new INVITE.
2. If there is an ongoing INVITE server transaction, the TU MUST
wait until the transaction reaches the confirmed or terminated
state before initiating the new INVITE.
So you should wait to retrieve the ACK first to be sure about that the first INVITE is done processing, because according to result of INVITE transaction, some message is expected to close the dialog . For an accepted INVITE, this needed message is ACK. After that you can send RE-INVITE to make some changes about SDP or something.
Consider this sample SIP dialog
A-->--INVITE-->--B CSeq 101
A--<--TRYING--<--B CSeq 101
A--<--200 OK--<--B CSeq 101
A-->-- ACK -->--B CSeq 101
A-->-- INFO -->--B CSeq 2
A--<-- 500 --<--B CSeq 2
...
While working on a SIP handling code, we put a validation for CSeq of a SIP INFO message for a dialog to be greater than the one sent for the INVITE.
However, as shown in the above SIP flow, one of the remote SIP gateways is sending it to be lower, ie 2 instead of the expected 102 or higher.
The RFC https://www.ietf.org/rfc/rfc3261.txt states that
Requests within a dialog MUST contain strictly monotonically
increasing and contiguous CSeq sequence numbers (increasing-by-one) in
each direction
So, is the observed behavior a violation of the RFC?
Yes, it is. You paraphrased the correct text.
The RFC on SIP INFO messages states CSeq header values follow the mechanism in RFC3261:
The Info Package mechanism does not define a delivery order
mechanism. Info Packages can rely on the CSeq header field [RFC3261]
to detect if an INFO request is received out of order.
However, keep in mind you can't rely on the received CSeq number being only one higher than the previously received one (https://www.rfc-editor.org/rfc/rfc3261#section-12.2.2):
It is possible for the
CSeq sequence number to be higher than the remote sequence number by
more than one. This is not an error condition, and a UAS SHOULD be
prepared to receive and process requests with CSeq values more than
one higher than the previous received request. The UAS MUST then set
the remote sequence number to the value of the sequence number in the
CSeq header field value in the request.
If a proxy challenges a request generated by the UAC, the UAC has
to resubmit the request with credentials. The resubmitted request
will have a new CSeq number. The UAS will never see the first
request, and thus, it will notice a gap in the CSeq number space.
Such a gap does not represent any error condition.
I'm using SipUnit to test my sip application which just forward the request. In my simple test case, user1(simulated with SipPhone) send Subscribe request and my application forward the request to user2(simulated
with SipPhone) and then user2 send reply by using JAIN ServerTransaction.sendResponse() method.
Then user2 send Notify to user1 using JAIN SipDialog.sendRequest().
And from the wireshark there is a problem in this Notify request: the CSeq is "1 Notify", but it should be "2 Notify" as it is in the same dialog as the Subscribe so the sequence number should be increased by 1.
Any idea?
When one party (say A) sends SUBSCRIBE to another (say B), then the NOTIFY will typically come from the B side and each direction, both (A to B) and (B to A) count the requests separately. So SUBSCRIBE will be CSeq 1 from A to B, and the NOTIFY will be CSeq 1 from B to A.
ACK is considered as a separated transaction when INVITE has a 200 OK response.
But a request associated with all the responses untill a final response is obtained is considered as a transaction.
How ACK request In SIP INVITE is called a transaction when there is no response for it.
When the UAC receives 200 OK, the client transaction is destroyed at TL.
This is done because, the TL is unaware of the above core. The above
core can be a Proxy or an UAC core.
In case of proxy, the 200 OK is forwarded whereas in case of UAC, an
ACK is generated. Now this ACK has to
create a new transaction (transaction created by INVITE had been
destroyed)at TL for its transmission, hence the ACK for 200 OK is
outside the INVITE transaction.
For other non-2xx final responses, the client transaction at TL is not
destroyed and the ACK is generated by TL.
Hence in this case, the ACK is within the transaction.
I have a Kamailio 4.0.4 proxy (K) running registrar and tm. There are multiple clients for some AORs and they all auto-accept certain INVITEs which is causing a race condition and having 200 OKs from multiple branches being sent to the callee.
Scenario:
- A sends invite to B
K finds 2 contacts in the uloc for B, let's call them B1 & B2
INVITE is branched and sent to B1 and B2
Note: B1 has a link latency of 100ms and B2 latency of 150ms
Both B1 and B2 auto-accept with 200 OK instantly as they get it
200ms after branching INVITE, K gets 200 OK from B1 and relays it to A
K also CANCELs the INVITE to B2
A is actually a local AS which ACKs the 200 OK back to B1 instantly
Now the problem is that B2 already sent a 200 OK 50ms ago and won't be receiving the CANCEL for another 150ms
So the 200 OK from B2 comes to K but the call is already setup between A and B1
What happens is that the 200 OK is relayed to A which at this point gets utterly confused because it's not a very good AS to be honest.
Now to the actual question, how do I stop the extra 200 OK from going to A?
I can see a few options of how it should work:
Drop the 200 OK, just throw it away. B2 should not resend it because the CANCEL will hit it soon
ACK + BYE the 200 OK from inside Kamailio, but this will result in a media session being brought up and torn down immediately by B2
I can't even find an RFC covering this race condition..
IIRC, according to the rfc, the 200ok responses have to be always forwarded, being the decision of caller to pick one and send a ACK+BYE for the other.
The easy solution with kamailio is to drop any 200ok once you got one. The callee might not stop resending it even when a CANCEL arrives, will wait for ACK and eventually BYE.
TM module will always forward the 200ok, as per rfc. If you want to drop in kamailio.cfg, a possible solution:
use reply_route { ... } block to intercept 200ok for invite
use htable to store when first 200ok is received (the key can be call-id)
use cfgutils to get locks that will protect against races to access/update the htable
processing logic: if it is a 200ok for INVITE, lock for htable, check if there is a key for that callid. If yes, unlock and drop. If not, add an item with call-id as a key, unlock and let the response go on