⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialogset.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
#include "resip/stack/Helper.hxx"#include "resip/dum/AppDialog.hxx"#include "resip/dum/AppDialogSet.hxx"#include "resip/dum/BaseCreator.hxx"#include "resip/dum/ClientAuthManager.hxx"#include "resip/dum/ClientOutOfDialogReq.hxx"#include "resip/dum/ClientPublication.hxx"#include "resip/dum/ClientRegistration.hxx"#include "resip/dum/ClientPagerMessage.hxx"#include "resip/dum/ServerPagerMessage.hxx"#include "resip/dum/Dialog.hxx"#include "resip/dum/DialogSet.hxx"#include "resip/dum/DialogSetHandler.hxx"#include "resip/dum/DialogUsageManager.hxx"#include "resip/dum/MasterProfile.hxx"#include "resip/dum/RedirectManager.hxx"#include "resip/dum/UsageUseException.hxx"#include "resip/dum/ServerOutOfDialogReq.hxx"#include "resip/dum/ServerRegistration.hxx"#include "resip/dum/DumHelper.hxx"#include "resip/dum/SubscriptionCreator.hxx"#include "rutil/Logger.hxx"#include "rutil/Inserter.hxx"#include "rutil/WinLeakCheck.hxx"#define RESIPROCATE_SUBSYSTEM Subsystem::DUMusing namespace resip;using namespace std;// UAC DialogSet::DialogSet(BaseCreator* creator, DialogUsageManager& dum) :   mMergeKey(),   mDialogs(),   mCreator(creator),   mId(*creator->getLastRequest()),   mDum(dum),   mAppDialogSet(0),   mState(Initial),   mClientRegistration(0),   mServerRegistration(0),   mClientPublication(0),   mClientOutOfDialogRequests(),   mServerOutOfDialogRequest(0),   mClientPagerMessage(0),   mServerPagerMessage(0){   setUserProfile(creator->getUserProfile());   assert(!creator->getLastRequest()->isExternal());   DebugLog ( << " ************* Created DialogSet(UAC)  -- " << mId << "*************" );}// UAS DialogSet::DialogSet(const SipMessage& request, DialogUsageManager& dum) :   mMergeKey(request, dum.getMasterProfile()->checkReqUriInMergeDetectionEnabled()),   mDialogs(),   mCreator(0),   mId(request),   mDum(dum),   mAppDialogSet(0),   mState(Established),   mClientRegistration(0),   mServerRegistration(0),   mClientPublication(0),   mClientOutOfDialogRequests(),   mServerOutOfDialogRequest(0),   mClientPagerMessage(0),   mServerPagerMessage(0){   assert(request.isRequest());   assert(request.isExternal());   mDum.mMergedRequests.insert(mMergeKey);   if (request.header(h_RequestLine).method() == INVITE)   {      if(mDum.mCancelMap.count(request.getTransactionId()) != 0)      {         WarningLog ( << "An endpoint is using the same tid in multiple INVITE requests, ability to match CANCEL requests correctly may be comprimised, tid=" << request.getTransactionId() );      }      mCancelKey = request.getTransactionId();      mDum.mCancelMap[mCancelKey] = this;   }   DebugLog ( << " ************* Created DialogSet(UAS)  -- " << mId << "*************" );}DialogSet::~DialogSet(){   if (mDum.mClientAuthManager.get())   {      mDum.mClientAuthManager->dialogSetDestroyed(getId());   }   if (mMergeKey != MergedRequestKey::Empty)   {      mDum.requestMergedRequestRemoval(mMergeKey);   }   if (!mCancelKey.empty())   {      mDum.mCancelMap.erase(mCancelKey);   }   delete mCreator;   while(!mDialogs.empty())   {      delete mDialogs.begin()->second;   }   delete mClientRegistration;   delete mServerRegistration;   delete mClientPublication;   delete mServerOutOfDialogRequest;   delete mClientPagerMessage;   delete mServerPagerMessage;   while (!mClientOutOfDialogRequests.empty())   {      delete *mClientOutOfDialogRequests.begin();   }   DebugLog ( << " ********** DialogSet::~DialogSet: " << mId << "*************" );   //!dcm! -- very delicate code, change the order things go horribly wrong   mDum.removeDialogSet(this->getId());   if (mAppDialogSet)    {      mAppDialogSet->destroy();   }}void DialogSet::possiblyDie(){   if(mState != Destroying &&      mDialogs.empty() &&      // The following check ensures we are not a UAC DialogSet in the Initial or       // ReceivedProvisional states.      // .slg. this check fixes a case where we might receive a short term usuage       //       request (such as OPTIONS) in the same dialogset as a UAC dialogset      //       for which we have not created any Dialogs yet - in this case      //       we don't want the dialogset to die, since the UAC usage is not complete.           (mCreator == 0 || (mState != Initial && mState != ReceivedProvisional)) &&        mClientOutOfDialogRequests.empty() &&      !(mClientPublication ||        mServerOutOfDialogRequest ||        mClientPagerMessage ||        mServerPagerMessage ||        mClientRegistration ||        mServerRegistration))   {      mState = Destroying;      mDum.destroy(this);   }}DialogSetIdDialogSet::getId() const{   return mId;}voidDialogSet::addDialog(Dialog *dialog){   mDialogs[dialog->getId()] = dialog;}BaseCreator*DialogSet::getCreator(){   return mCreator;}Dialog*DialogSet::findDialog(const SipMessage& msg){   if (msg.isResponse() && msg.header(h_StatusLine).statusCode() == 100)   {      return 0;   }   return findDialog(DialogId(msg));#if 0      DialogId id(msg);   Dialog* dlog = findDialog(id);   //vonage/2543 matching here   if (dlog)   {      return dlog;   }   //match off transaction ID   else if (msg.isResponse() && !msg.header(h_To).exists(p_tag))   {      for(DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++)      {         if (it->second->matches(msg))         {            return it->second;                     }      }   }   else if (msg.exists(h_Contacts) && !msg.header(h_Contacts).empty()            && msg.isResponse()             && mDum.getProfile()->looseToTagMatching()            && msg.header(h_To).exists(p_tag))        {      const Uri& contact = msg.header(h_Contacts).front().uri();            //match by contact      for(DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++)      {         if (it->second->mRemoteTarget.uri() == msg.header(h_Contacts).front().uri())         {            //!dcm! in the vonage case, the to tag should be updated to match the fake            //vonage tag introduced in the 200 which is also used for the BYE.            //find out how deep this rabbit hole goes, may just have a pugabble            //filter api that can be added for dialog matching if things get any            //more specific--this is the VonageKludgeFilter            Dialog* dialog = it->second;            DialogId old = dialog->getId();            dialog->mId = DialogId(old.getCallId(), old.getLocalTag(), msg.header(h_To).param(p_tag));            dialog->mRemoteNameAddr.param(p_tag) = msg.header(h_To).param(p_tag);            mDialogs.erase(it);            mDialogs[dialog->getId()] = dialog;            return dialog;         }      }   }   return 0;#endif}boolDialogSet::empty() const{   return mDialogs.empty();}boolDialogSet::handledByAuthOrRedirect(const SipMessage& msg){   if (msg.isResponse() && !(mState == Terminating || mState == WaitingToEnd || mState == Destroying))   {      //!dcm! -- multiple usage grief...only one of each method type allowed      if (getCreator() &&          msg.header(h_CSeq) == getCreator()->getLastRequest()->header(h_CSeq))      {         if (mDum.mClientAuthManager.get())         {            if (mDum.mClientAuthManager->handle(*getUserProfile().get(), *getCreator()->getLastRequest(), msg))            {               // Note:  ClientAuthManager->handle will end up incrementing the CSeq sequence of getLastRequest               DebugLog( << "about to re-send request with digest credentials" );               StackLog( << getCreator()->getLastRequest() );                              mDum.send(getCreator()->getLastRequest());               return true;                                 }         }         //!dcm! -- need to protect against 3xx highjacking a dialogset which         //has a fully established dialog. also could case strange behaviour         //by sending 401/407 at the wrong time.         if (mDum.mRedirectManager.get() && mState != Established)  // !slg! for now don't handle redirect in established dialogs - alternatively we could treat as a target referesh (using 1st Contact) and reissue request         {            if (mDum.mRedirectManager->handle(*this, *getCreator()->getLastRequest(), msg))            {               //terminating existing dialogs(branches) as this is a final               //response--?dcm?--merge w/ forking logic somehow?                                             //!dcm! -- really, really horrible.  Should make a don't die               //scoped guard               mState = Initial;                              for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); ++it)               {                  it->second->redirected(msg);                        }               InfoLog( << "about to re-send request to redirect destination" );               DebugLog( << getCreator()->getLastRequest() );                              mDum.send(getCreator()->getLastRequest());               return true;                                 }            // Check if a 422 response to initial Invite (RFC4028)            if(msg.header(h_StatusLine).statusCode() == 422 && msg.exists(h_MinSE))            {               // Change interval to min from 422 response               getCreator()->getLastRequest()->header(h_SessionExpires).value() = msg.header(h_MinSE).value();               getCreator()->getLastRequest()->header(h_MinSE).value() = msg.header(h_MinSE).value();               getCreator()->getLastRequest()->header(h_CSeq).sequence()++;               InfoLog( << "about to re-send request with new session expiration time" );               DebugLog( << getCreator()->getLastRequest() );                              mDum.send(getCreator()->getLastRequest());               return true;                                 }         }      }   }   return false;}voidDialogSet::dispatch(const SipMessage& msg){   if(!mAppDialogSet)   {      // !bwc! There are conditions where reuse of the AppDialogSet will cause      // us to hit this code. This is because the teardown of DialogSets is not      // atomic, causing the DialogSet to hang around for a short time after it      // has given up its AppDialogSet. Also, if we have multiple Usages in      // this DialogSet, one of the Usages may decide to re-establish itself in       // a new Dialog, and take the AppDialogSet with it, leaving all the others      // high and dry. This is a design issue that will take some real effort to      // fix properly. This is a band-aid for now.      // TODO fix this properly      if(msg.isRequest())      {         if(msg.method() != ACK)         {            SipMessage err;            Helper::makeResponse(err, msg, 500, "DialogSet: My AppDialogSet is "                                       "missing!");            mDum.sendResponse(err);         }      }      else      {         ErrLog(<<"Response came in, but no AppDialogSet! Dropping this is very"                  "likely to cause leaks, but continuing to process it is "                  "likely to cause a core. Taking the lesser of two evils...");      }      return;   }   assert(msg.isRequest() || msg.isResponse());   if (mState == WaitingToEnd)   {      assert(mDialogs.empty());      if (msg.isResponse())               {         int code = msg.header(h_StatusLine).statusCode();         switch(mCreator->getLastRequest()->header(h_CSeq).method())         {            case INVITE:               if (code / 100 == 1)               {                  mState = ReceivedProvisional;                  end();               }               else if (code / 100 == 2)               {                  Dialog dialog(mDum, msg, *this);                  SharedPtr<SipMessage> ack(new SipMessage);                  dialog.makeRequest(*ack, ACK);                  ack->header(h_CSeq).sequence() = msg.header(h_CSeq).sequence();                  dialog.send(ack);                                    SharedPtr<SipMessage> bye(new SipMessage);                  dialog.makeRequest(*bye, BYE);                  dialog.send(bye);                  // Note:  Destruction of this dialog object will cause DialogSet::possiblyDie to be called thus invoking mDum.destroy               }               else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -