< Previous by Date Date Index Next by Date >
  Thread Index Next in Thread >

[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);
    }
 }