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

📄 sipmessage.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 4 页
字号:
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include "resip/stack/Contents.hxx"#include "resip/stack/Embedded.hxx"#include "resip/stack/OctetContents.hxx"#include "resip/stack/HeaderFieldValueList.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/stack/ExtensionHeader.hxx"#include "rutil/Coders.hxx"#include "rutil/CountStream.hxx"#include "rutil/Logger.hxx"#include "rutil/MD5Stream.hxx"#include "rutil/compat.hxx"#include "rutil/vmd5.hxx"#include "rutil/Coders.hxx"#include "rutil/Random.hxx"#include "rutil/ParseBuffer.hxx"#include "resip/stack/MsgHeaderScanner.hxx"#include "rutil/WinLeakCheck.hxx"using namespace resip;using namespace std;#define RESIPROCATE_SUBSYSTEM Subsystem::SIPbool SipMessage::checkContentLength=true;SipMessage::SipMessage(const Transport* fromWire)   : mIsDecorated(false),     mIsBadAck200(false),          mIsExternal(fromWire != 0),     mTransport(fromWire),     mStartLine(0),     mContentsHfv(0),     mContents(0),     mRFC2543TransactionId(),     mRequest(false),     mResponse(false),     mInvalid(false),     mCreatedTime(Timer::getTimeMicroSec()),     mForceTarget(0),     mTlsDomain(Data::Empty){   for (int i = 0; i < Headers::MAX_HEADERS; i++)   {      mHeaders[i] = 0;   }}SipMessage::SipMessage(const SipMessage& from)   : mStartLine(0),     mContentsHfv(0),     mContents(0),     mCreatedTime(Timer::getTimeMicroSec()),     mForceTarget(0){   for (int i = 0; i < Headers::MAX_HEADERS; i++)   {      mHeaders[i] = 0;   }   *this = from;}Message*SipMessage::clone() const{   return new SipMessage(*this);}SipMessage& SipMessage::operator=(const SipMessage& rhs){   if (this != &rhs)   {      this->cleanUp();      mIsDecorated = rhs.mIsDecorated;      mIsBadAck200 = rhs.mIsBadAck200;      mIsExternal = rhs.mIsExternal;      mTransport = rhs.mTransport;      mSource = rhs.mSource;      mDestination = rhs.mDestination;      mStartLine = 0;      mContentsHfv = 0;      mContents = 0;      mRFC2543TransactionId = rhs.mRFC2543TransactionId;      mRequest = rhs.mRequest;      mResponse = rhs.mResponse;      mInvalid = rhs.mInvalid;      mReason = rhs.mReason;      mForceTarget = 0;      mTlsDomain = rhs.mTlsDomain;            for (int i = 0; i < Headers::MAX_HEADERS; i++)      {         if (rhs.mHeaders[i] != 0)         {            mHeaders[i] = new HeaderFieldValueList(*rhs.mHeaders[i]);         }         else         {            mHeaders[i] = 0;         }      }        for (UnknownHeaders::const_iterator i = rhs.mUnknownHeaders.begin();           i != rhs.mUnknownHeaders.end(); i++)      {         mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(                                      i->first,                                      new HeaderFieldValueList(*i->second)));      }      if (rhs.mStartLine != 0)      {         mStartLine = new HeaderFieldValueList(*rhs.mStartLine);       }      if (rhs.mContents != 0)      {         mContents = rhs.mContents->clone();      }      else if (rhs.mContentsHfv != 0)      {         mContentsHfv = new HeaderFieldValue(*rhs.mContentsHfv, HeaderFieldValue::CopyPadding);      }      else      {         // no body to copy      }      if (rhs.mForceTarget != 0)      {         mForceTarget = new Uri(*rhs.mForceTarget);      }      if (rhs.mSecurityAttributes.get())      {         if (!mSecurityAttributes.get())         {            SecurityAttributes* attr = new SecurityAttributes();            mSecurityAttributes.reset(attr);         }         if (rhs.mSecurityAttributes->isEncrypted())         {            mSecurityAttributes->setEncrypted();         }         mSecurityAttributes->setSignatureStatus(rhs.mSecurityAttributes->getSignatureStatus());         mSecurityAttributes->setIdentity(rhs.mSecurityAttributes->getIdentity());         mSecurityAttributes->setIdentityStrength(rhs.mSecurityAttributes->getIdentityStrength());         mSecurityAttributes->setSigner(rhs.mSecurityAttributes->getSigner());         mSecurityAttributes->setOutgoingEncryptionLevel(rhs.mSecurityAttributes->getOutgoingEncryptionLevel());         mSecurityAttributes->setEncryptionPerformed(rhs.mSecurityAttributes->encryptionPerformed());      }      else      {         if (mSecurityAttributes.get())         {            mSecurityAttributes.reset();         }      }      mOutboundDecorators = rhs.mOutboundDecorators;   }   return *this;}SipMessage::~SipMessage(){   cleanUp();}voidSipMessage::cleanUp(){   for (int i = 0; i < Headers::MAX_HEADERS; i++)   {      delete mHeaders[i];      mHeaders[i] = 0;   }   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();        i != mUnknownHeaders.end(); i++)   {      delete i->second;   }   mUnknownHeaders.clear();      for (vector<char*>::iterator i = mBufferList.begin();        i != mBufferList.end(); i++)   {      delete [] *i;   }   mBufferList.clear();   delete mStartLine;   mStartLine = 0;   delete mContents;   mContents = 0;   delete mContentsHfv;   mContentsHfv = 0;   delete mForceTarget;   mForceTarget = 0;}SipMessage*SipMessage::make(const Data& data,  bool isExternal){   Transport* external = (Transport*)(0xFFFF);   SipMessage* msg = new SipMessage(isExternal ? external : 0);   size_t len = data.size();   char *buffer = new char[len + 5];   msg->addBuffer(buffer);   memcpy(buffer,data.data(), len);   MsgHeaderScanner msgHeaderScanner;   msgHeaderScanner.prepareForMessage(msg);      char *unprocessedCharPtr;   if (msgHeaderScanner.scanChunk(buffer, len, &unprocessedCharPtr) != MsgHeaderScanner::scrEnd)   {      DebugLog(<<"Scanner rejecting buffer as unparsable / fragmented.");      DebugLog(<< data);      delete msg;       msg = 0;       return 0;   }   // no pp error   unsigned int used = unprocessedCharPtr - buffer;   if (used < len)   {      // body is present .. add it up.      // NB. The Sip Message uses an overlay (again)      // for the body. It ALSO expects that the body      // will be contiguous (of course).      // it doesn't need a new buffer in UDP b/c there      // will only be one datagram per buffer. (1:1 strict)      msg->setBody(buffer+used,len-used);      //DebugLog(<<"added " << len-used << " byte body");   }   return msg;}voidSipMessage::parseAllHeaders(){   for (int i = 0; i < Headers::MAX_HEADERS; i++)   {      ParserContainerBase* pc=0;      if(mHeaders[i])      {         ensureHeaders((Headers::Type)i,!Headers::isMulti((Headers::Type)i));         if(!(pc=mHeaders[i]->getParserContainer()))         {            pc = HeaderBase::getInstance((Headers::Type)i)->makeContainer(mHeaders[i]);            mHeaders[i]->setParserContainer(pc);         }               pc->parseAll();      }   }   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();        i != mUnknownHeaders.end(); i++)   {      ParserContainerBase* scs=0;      if(!(scs=i->second->getParserContainer()))      {         scs=new ParserContainer<StringCategory>(i->second,Headers::RESIP_DO_NOT_USE);         i->second->setParserContainer(scs);      }            scs->parseAll();   }      assert(mStartLine);   ParserContainerBase* slc = 0;   if(!(slc=mStartLine->getParserContainer()))   {      if(mRequest)      {         slc=new ParserContainer<RequestLine>(mStartLine,Headers::NONE);      }      else if(mResponse)      {         slc=new ParserContainer<StatusLine>(mStartLine,Headers::NONE);      }      else      {         assert(0);      }      mStartLine->setParserContainer(slc);   }   slc->parseAll();      getContents();}const Data& SipMessage::getTransactionId() const{   if (!this->exists(h_Vias) || this->header(h_Vias).empty())   {      InfoLog (<< "Bad message with no Vias: " << *this);      throw Exception("No Via in message", __FILE__,__LINE__);   }      assert(exists(h_Vias) && !header(h_Vias).empty());   if( exists(h_Vias) && header(h_Vias).front().exists(p_branch)        && header(h_Vias).front().param(p_branch).hasMagicCookie()        && (!header(h_Vias).front().param(p_branch).getTransactionId().empty())     )   {      return header(h_Vias).front().param(p_branch).getTransactionId();   }   else   {      if (mRFC2543TransactionId.empty())      {         compute2543TransactionHash();      }      return mRFC2543TransactionId;   }}voidSipMessage::compute2543TransactionHash() const{   assert (mRFC2543TransactionId.empty());      /*  From rfc3261, 17.2.3       The INVITE request matches a transaction if the Request-URI, To tag,       From tag, Call-ID, CSeq, and top Via header field match those of the       INVITE request which created the transaction.  In this case, the       INVITE is a retransmission of the original one that created the       transaction.         The ACK request matches a transaction if the Request-URI, From tag,       Call-ID, CSeq number (not the method), and top Via header field match       those of the INVITE request which created the transaction, and the To       tag of the ACK matches the To tag of the response sent by the server       transaction.         Matching is done based on the matching rules defined for each of those       header fields.  Inclusion of the tag in the To header field in the ACK       matching process helps disambiguate ACK for 2xx from ACK for other       responses at a proxy, which may have forwarded both responses (This       can occur in unusual conditions.  Specifically, when a proxy forked a       request, and then crashes, the responses may be delivered to another       proxy, which might end up forwarding multiple responses upstream).  An       ACK request that matches an INVITE transaction matched by a previous       ACK is considered a retransmission of that previous ACK.       For all other request methods, a request is matched to a transaction       if the Request-URI, To tag, From tag, Call-ID, CSeq (including the       method), and top Via header field match those of the request that       created the transaction.  Matching is done based on the matching   */   // If it is here and isn't a request, leave the transactionId empty, this   // will cause the Transaction to send it statelessly   if (isRequest())   {      MD5Stream strm;      // See section 17.2.3 Matching Requests to Server Transactions in rfc 3261//#define VONAGE_FIX#ifndef VONAGE_FIX               strm << header(h_RequestLine).uri().scheme();      strm << header(h_RequestLine).uri().user();      strm << header(h_RequestLine).uri().host();      strm << header(h_RequestLine).uri().port();      strm << header(h_RequestLine).uri().password();      strm << header(h_RequestLine).uri().commutativeParameterHash();#endif      if (exists(h_Vias) && !header(h_Vias).empty())      {         strm << header(h_Vias).front().protocolName();         strm << header(h_Vias).front().protocolVersion();         strm << header(h_Vias).front().transport();         strm << header(h_Vias).front().sentHost();         strm << header(h_Vias).front().sentPort();         strm << header(h_Vias).front().commutativeParameterHash();      }               if (header(h_From).exists(p_tag))      {         strm << header(h_From).param(p_tag);      }      // Only include the totag for non-invite requests      if (header(h_RequestLine).getMethod() != INVITE &&           header(h_RequestLine).getMethod() != ACK &&           header(h_RequestLine).getMethod() != CANCEL &&          header(h_To).exists(p_tag))      {         strm << header(h_To).param(p_tag);      }      strm << header(h_CallID).value();

⌨️ 快捷键说明

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