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

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


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