Commit e86a630 for jssip.net
commit e86a6302b015c5b5a8d6ee71e1b48a9ddcf29f0c
Author: José Luis Millán <jmillan@aliax.net>
Date: Thu Jan 8 13:27:44 2026 +0100
Dialog: Fix wrong ACK Cseq for re-INVITE
Fixes #943
diff --git a/lib/Dialog.js b/lib/Dialog.js
index 9454142..8ec47a6 100644
--- a/lib/Dialog.js
+++ b/lib/Dialog.js
@@ -63,7 +63,8 @@ module.exports = class Dialog
this._remote_uri = message.parseHeader('from').uri;
this._remote_target = contact.uri;
this._route_set = message.getHeaders('record-route');
- this._ack_seqnum = message.cseq;
+ this.incoming_ack_seqnum = message.cseq;
+ this.outgoing_ack_seqnum = null;
}
// RFC 3261 12.1.2.
else if (type === 'UAC')
@@ -83,7 +84,8 @@ module.exports = class Dialog
this._remote_uri = message.parseHeader('to').uri;
this._remote_target = contact.uri;
this._route_set = message.getHeaders('record-route').reverse();
- this._ack_seqnum = this._local_seqnum;
+ this.incoming_ack_seqnum = null;
+ this.outgoing_ack_seqnum = this._local_seqnum;
}
@@ -163,6 +165,12 @@ module.exports = class Dialog
eventHandlers.onAuthenticated = () =>
{
this._local_seqnum += 1;
+
+ // In case of re-INVITE store outgoing ack_seqnum for its CANCEL or ACK.
+ if (request.method === JsSIP_C.INVITE)
+ {
+ this._outgoing_ack_seqnum = this._local_seqnum;
+ }
};
const request_sender = new Dialog_RequestSender(this, request, eventHandlers);
@@ -182,14 +190,14 @@ module.exports = class Dialog
}
// ACK received. Cleanup this._ack_seqnum.
- if (request.method === JsSIP_C.ACK && this._ack_seqnum !== null)
+ if (request.method === JsSIP_C.ACK && this.incoming_ack_seqnum !== null)
{
- this._ack_seqnum = null;
+ this.incoming_ack_seqnum = null;
}
// INVITE received. Set this._ack_seqnum.
else if (request.method === JsSIP_C.INVITE)
{
- this._ack_seqnum = request.cseq;
+ this.incoming_ack_seqnum = request.cseq;
}
this._owner.receiveRequest(request);
@@ -204,9 +212,15 @@ module.exports = class Dialog
// CANCEL and ACK must use the same sequence number as the INVITE.
const cseq = (method === JsSIP_C.CANCEL || method === JsSIP_C.ACK) ?
- this._ack_seqnum :
+ this.outgoing_ack_seqnum :
this._local_seqnum += 1;
+ // In case of re-INVITE store ack_seqnum for future CANCEL or ACK.
+ if (method === JsSIP_C.INVITE)
+ {
+ this.outgoing_ack_seqnum = cseq;
+ }
+
const request = new SIPMessage.OutgoingRequest(
method,
this._remote_target,
@@ -237,7 +251,8 @@ module.exports = class Dialog
{
// We are not expecting any ACK with lower seqnum than the current one.
// Or this is not the ACK we are waiting for.
- if (this._ack_seqnum === null || request.cseq !== this._ack_seqnum)
+ if (this.incoming_ack_seqnum === null ||
+ request.cseq !== this.incoming_ack_seqnum)
{
return false;
}