[reSIProcate] DUM UAS 1xx response retransmitted more times
Hi,
DUM's UAS sends provisional retransmits more times. Let's say UAS
responses with 100, 183 and 180 to an INVITE. In this case 180 will be
repeated 3 times after a minute. The reason is that DUM starts
Retransmit1xx timer on every provisional response. When a timer is
triggered it is checked by CSeq if it belongs to the last response. But
CSeq is always the same as all the responses reply to the same request.
Hence all of the 3 timers will cause a 180 retransmission.
In the attached patch ServerInviteSession::mCurrentRetransmit1xx is used
as a provisional response sequence counter and checked instead of CSeq.
Also it does not start the timer for 100 as RFC3261 13.3.1 says the UAS
must send a non-100 provisional response every minute.
It is based on resiprocate-1.7 but as I can see this issue is the same
in the latest version as well.
Please check it and feel free to correct me. I am not sure if I
understand correctly the purpose of mCurrentRetransmit1xx.
Kind Regards,
Tibor
diff -ruwx .svn resiprocate-1.7/resip/dum/ServerInviteSession.cxx resiprocate/resip/dum/ServerInviteSession.cxx
--- resiprocate-1.7/resip/dum/ServerInviteSession.cxx 2013-06-12 11:24:43.806778286 +0000
+++ resiprocate/resip/dum/ServerInviteSession.cxx 2013-06-12 14:20:08.612146667 +0000
@@ -707,7 +707,7 @@
{
if (timeout.type() == DumTimeout::Retransmit1xx)
{
- if (mCurrentRetransmit1xx && m1xx->header(h_CSeq).sequence() == timeout.seq()) // If timer isn't stopped and this timer is for last 1xx sent, then resend
+ if (mCurrentRetransmit1xx == timeout.secondarySeq()) // If timer isn't stopped and this timer is for last 1xx sent, then resend
{
send(m1xx);
startRetransmit1xxTimer();
@@ -1211,11 +1211,11 @@
ServerInviteSession::startRetransmit1xxTimer()
{
// RFC3261 13.3.1 says the UAS must send a non-100 provisional response every minute, to handle the possiblity of lost provisional responses
- mCurrentRetransmit1xx = mDialog.mDialogSet.getUserProfile()->get1xxRetransmissionTime();
- if(mCurrentRetransmit1xx > 0)
+ int retransmissionTime = mDialog.mDialogSet.getUserProfile()->get1xxRetransmissionTime();
+ if (retransmissionTime > 0 && m1xx->header(resip::h_StatusLine).statusCode() > 100)
{
unsigned int seq = m1xx->header(h_CSeq).sequence();
- mDum.addTimer(DumTimeout::Retransmit1xx, mCurrentRetransmit1xx, getBaseHandle(), seq);
+ mDum.addTimer(DumTimeout::Retransmit1xx, retransmissionTime, getBaseHandle(), seq, ++mCurrentRetransmit1xx);
}
}