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

Re: [reSIProcate] Target refresh in the wrong invitesession state causes abort


Hi Scott,

At first we had a similar patch, but it turns out it's too late to reject the request in InviteSession, because by then the contact have been overwritten by the Dialog's handleTargetRefresh(). That is why we put the reject right before the call to handleTargetRefresh().

br

Szo

On 2016-04-20 21:49, Scott Godin wrote:
Hi Robert,

It appears there are actually more states we don't handle this properly in.  I took a different approach and put in "catch all" like handling for inbound INVITEs and UPDATEs in dispatchOthers.  If an INVITE or UPDATE makes it here, we will respond with a 491.

Can you try out the following code and see if it works for you?

void
InviteSession::dispatchOthers(const SipMessage& msg)
{
   // handle OnGeneralFailure
   // handle OnRedirect

   switch (msg.header(h_CSeq).method())
   {
      case INVITE:
      case UPDATE:
         if (msg.isRequest())
         {
            SharedPtr<SipMessage> response(new SipMessage);
            mDialog.makeResponse(*response, msg, 491);
            send(response);
            break;
         }
      case PRACK:
         dispatchPrack(msg);
         break;
      case CANCEL:
         dispatchCancel(msg);
         break;
      case BYE:
         dispatchBye(msg);
         break;
      case INFO:
         dispatchInfo(msg);
         break;
      case MESSAGE:
         dispatchMessage(msg);
         break;
      case ACK:
         // Ignore duplicate ACKs from 2xx reTransmissions
         break;
      default:
         // handled in Dialog
         WarningLog (<< "DUM delivered a "
                     << msg.header(h_CSeq).unknownMethodName()
                     << " to the InviteSession in state: " << toData(mState)
                     << endl
                     << msg);
         resip_assert(0);
         break;
   }
}

Best Regards,
Scott

On Thu, Apr 14, 2016 at 9:18 AM, Szokovacs Robert <robert.szokovacs@xxxxxxxxxxx> wrote:
Hi,

We have experienced a crash (abort) in our resiprocate-based B2BUA, in
this scenario:
we use rtpproxy, but when it turns out to be unnecessary, we drop it
using a pair of reinvites:
1, SDP-less invite to C
2, OK from C with SDP offer
3, pass on the SDP offer in invite to A,
4, OK from A with SDP answer
5, pass on the SDP answer in ACK to C,
6, ACK to A

we also have an upstream SBC, which have multiple instances with
fail-over capabilities. When one of the instances fail, the fail-over
sends "target refresh" INVITEs to our B2BUA. When these two happen
simultaneously (the reinvite being between step 2 and 5), the B2BUA will
crash in resiprocate:

3  0x00007f7880eb4e42 in __assert_fail () from
/lib/x86_64-linux-gnu/libc.so.6
#4  0x00000000007eb9e6 in resip::InviteSession::dispatchOthers
(this=0x7f784da84a50, msg=
    ...) at InviteSession.cxx:2039
#5  0x00000000007eaee8 in
resip::InviteSession::dispatchSentReinviteAnswered (
    this=0x7f784da84a50, msg=...) at InviteSession.cxx:1892
#6  0x00000000007e7209 in resip::InviteSession::dispatch
(this=0x7f784da84a50, msg=...)
    at InviteSession.cxx:1160
#7  0x000000000082fedd in resip::ClientInviteSession::dispatch
(this=0x7f784da84a50,
    msg=...) at ClientInviteSession.cxx:450
#8  0x00000000007a5426 in resip::Dialog::dispatch (this=0x7f784cdf4520,
msg=...)
    at Dialog.cxx:427
#9  0x00000000007b56e7 in resip::DialogSet::dispatch
(this=0x7f783f04e200, msg=...)
    at DialogSet.cxx:895
#10 0x00000000007c7fe6 in resip::DialogUsageManager::processRequest (
    this=0x7f7882f16fd8, request=...) at DialogUsageManager.cxx:1985
#11 0x00000000007c549f in resip::DialogUsageManager::incomingProcess (
    this=0x7f7882f16fd8, msg=...) at DialogUsageManager.cxx:1622
#12 0x00000000007c4595 in resip::DialogUsageManager::internalProcess (
    this=0x7f7882f16fd8, msg=...) at DialogUsageManager.cxx:1446
#13 0x00000000007c57cf in resip::DialogUsageManager::process
(this=0x7f7882f16fd8,
    mutex=0x0) at DialogUsageManager.cxx:1656

(the line numbers may vary, this trace is from an older resiprocate, but
the crash is reproducible with the latest, too).
We have a proposed patch, but we'd like to have a discussion about it,
so I post it here instead of creating the pull request right away:

Index: InviteSession.cxx
===================================================================
--- InviteSession.cxx   (revision 33950)
+++ InviteSession.cxx   (working copy)
@@ -299,6 +299,29 @@
 }

 bool
+InviteSession::isUpdating() const
+{
+   switch (mState)
+   {
+      case SentUpdate:
+      case SentUpdateGlare:
+      case SentReinvite:
+      case SentReinviteGlare:
+      case SentReinviteNoOffer:
+      case SentReinviteAnswered:
+      case SentReinviteNoOfferGlare:
+      case ReceivedUpdate:
+      case ReceivedReinvite:
+      case ReceivedReinviteNoOffer:
+      case ReceivedReinviteSentOffer:
+         return true;
+
+      default:
+         return false;
+   }
+}
+
+bool
 InviteSession::isEarly() const
 {
    switch (mState)
Index: InviteSession.hxx
===================================================================
--- InviteSession.hxx   (revision 33950)
+++ InviteSession.hxx   (working copy)
@@ -152,6 +152,7 @@
       const SdpContents& getProposedRemoteSdp() const;

       bool isConnected() const;
+      bool isUpdating() const;
       bool isTerminated() const;
       bool isEarly() const;     // UAC Early states
       bool isAccepted() const;  // UAS States after accept is called
Index: Dialog.cxx
===================================================================
--- Dialog.cxx  (revision 33950)
+++ Dialog.cxx  (working copy)
@@ -426,6 +426,14 @@
       }
    }

+   if(msg.isRequest() && INVITE == msg.header(h_CSeq).method() &&
+         mInviteSession != 0 && mInviteSession->isUpdating())
+   {
+     SipMessage failure;
+     makeResponse(failure, msg, 491);
+     mDum.sendResponse(failure);
+     return;
+   }
    handleTargetRefresh(msg);
    if (msg.isRequest())
    {


please comment

br

Szo
_______________________________________________
resiprocate-devel mailing list
resiprocate-devel@xxxxxxxxxxxxxxx
https://list.resiprocate.org/mailman/listinfo/resiprocate-devel