reSIProcate/stack  9694
SipMessage.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #include "resip/stack/Contents.hxx"
00006 #include "resip/stack/Embedded.hxx"
00007 #include "resip/stack/OctetContents.hxx"
00008 #include "resip/stack/HeaderFieldValueList.hxx"
00009 #include "resip/stack/SipMessage.hxx"
00010 #include "resip/stack/ExtensionHeader.hxx"
00011 #include "rutil/Coders.hxx"
00012 #include "rutil/CountStream.hxx"
00013 #include "rutil/Logger.hxx"
00014 #include "rutil/MD5Stream.hxx"
00015 #include "rutil/compat.hxx"
00016 #include "rutil/vmd5.hxx"
00017 #include "rutil/Coders.hxx"
00018 #include "rutil/Random.hxx"
00019 #include "rutil/ParseBuffer.hxx"
00020 #include "resip/stack/MsgHeaderScanner.hxx"
00021 //#include "rutil/WinLeakCheck.hxx"  // not compatible with placement new used below
00022 
00023 using namespace resip;
00024 using namespace std;
00025 
00026 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00027 
00028 bool SipMessage::checkContentLength=true;
00029 
00030 SipMessage::SipMessage(const Transport* fromWire)
00031    : mIsDecorated(false),
00032      mIsBadAck200(false),     
00033      mIsExternal(fromWire != 0),
00034      mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)),
00035 #ifndef __SUNPRO_CC
00036      mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)),
00037 #else
00038      mUnknownHeaders(),
00039 #endif
00040      mTransport(fromWire),
00041      mRFC2543TransactionId(),
00042      mRequest(false),
00043      mResponse(false),
00044      mInvalid(false),
00045      mCreatedTime(Timer::getTimeMicroSec()),
00046      mTlsDomain(Data::Empty)
00047 {
00048    // !bwc! TODO make this tunable
00049    mHeaders.reserve(16);
00050    clear();
00051 }
00052 
00053 SipMessage::SipMessage(const SipMessage& from)
00054    : mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)),
00055 #ifndef __SUNPRO_CC
00056      mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)),
00057 #else
00058      mUnknownHeaders(),
00059 #endif
00060      mCreatedTime(Timer::getTimeMicroSec())
00061 {
00062    init(from);
00063 }
00064 
00065 Message*
00066 SipMessage::clone() const
00067 {
00068    return new SipMessage(*this);
00069 }
00070 
00071 SipMessage& 
00072 SipMessage::operator=(const SipMessage& rhs)
00073 {
00074    if (this != &rhs)
00075    {
00076       freeMem();
00077       init(rhs);
00078    }
00079    return *this;
00080 }
00081 
00082 SipMessage::~SipMessage()
00083 {
00084    freeMem();
00085 }
00086 
00087 void
00088 SipMessage::clear(bool leaveResponseStuff)
00089 {
00090    if(!leaveResponseStuff)
00091    {
00092       memset(mHeaderIndices,0,sizeof(mHeaderIndices));
00093       mHeaders.clear();
00094       
00095       // !bwc! The "invalid" 0 index.
00096       mHeaders.push_back(getEmptyHfvl());
00097       mBufferList.clear();
00098    }
00099 
00100    mUnknownHeaders.clear();
00101 
00102    mStartLine = 0;
00103    mContents = 0;
00104    mContentsHfv.clear();
00105    mForceTarget = 0;
00106    mReason=0;
00107    mOutboundDecorators.clear();
00108 }
00109 
00110 void
00111 SipMessage::init(const SipMessage& rhs)
00112 {
00113    clear();
00114    mIsDecorated = rhs.mIsDecorated;
00115    mIsBadAck200 = rhs.mIsBadAck200;
00116    mIsExternal = rhs.mIsExternal;
00117    mTransport = rhs.mTransport;
00118    mSource = rhs.mSource;
00119    mDestination = rhs.mDestination;
00120    mRFC2543TransactionId = rhs.mRFC2543TransactionId;
00121    mRequest = rhs.mRequest;
00122    mResponse = rhs.mResponse;
00123    mInvalid = rhs.mInvalid;
00124    if(!rhs.mReason)
00125    {
00126       mReason=0;
00127    }
00128    else
00129    {
00130       mReason = new Data(*rhs.mReason);
00131    }
00132    mTlsDomain = rhs.mTlsDomain;
00133 
00134    memcpy(&mHeaderIndices,&rhs.mHeaderIndices,sizeof(mHeaderIndices));
00135 
00136    // .bwc. Clear out the pesky invalid 0 index.
00137    mHeaders.clear();
00138    mHeaders.reserve(rhs.mHeaders.size());
00139    for (TypedHeaders::const_iterator i = rhs.mHeaders.begin();
00140         i != rhs.mHeaders.end(); i++)
00141    {
00142       mHeaders.push_back(getCopyHfvl(**i));
00143    }
00144 
00145    for (UnknownHeaders::const_iterator i = rhs.mUnknownHeaders.begin();
00146         i != rhs.mUnknownHeaders.end(); i++)
00147    {
00148       mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(
00149                                    i->first,
00150                                    getCopyHfvl(*i->second)));
00151    }
00152    if (rhs.mStartLine != 0)
00153    {
00154       mStartLine = rhs.mStartLine->clone(mStartLineMem);
00155    }
00156    if (rhs.mContents != 0)
00157    {
00158       mContents = rhs.mContents->clone();
00159    }
00160    else if (rhs.mContentsHfv.getBuffer() != 0)
00161    {
00162       mContentsHfv.copyWithPadding(rhs.mContentsHfv);
00163    }
00164    else
00165    {
00166       // no body to copy
00167    }
00168    if (rhs.mForceTarget != 0)
00169    {
00170       mForceTarget = new Uri(*rhs.mForceTarget);
00171    }
00172 
00173    if (rhs.mSecurityAttributes.get())
00174    {
00175 
00176       if (!mSecurityAttributes.get())
00177       {
00178          SecurityAttributes* attr = new SecurityAttributes();
00179          mSecurityAttributes.reset(attr);
00180       }
00181 
00182       if (rhs.mSecurityAttributes->isEncrypted())
00183       {
00184          mSecurityAttributes->setEncrypted();
00185       }
00186       mSecurityAttributes->setSignatureStatus(rhs.mSecurityAttributes->getSignatureStatus());
00187       mSecurityAttributes->setIdentity(rhs.mSecurityAttributes->getIdentity());
00188       mSecurityAttributes->setIdentityStrength(rhs.mSecurityAttributes->getIdentityStrength());
00189       mSecurityAttributes->setSigner(rhs.mSecurityAttributes->getSigner());
00190       mSecurityAttributes->setOutgoingEncryptionLevel(rhs.mSecurityAttributes->getOutgoingEncryptionLevel());
00191       mSecurityAttributes->setEncryptionPerformed(rhs.mSecurityAttributes->encryptionPerformed());
00192    }
00193    else
00194    {
00195       if (mSecurityAttributes.get())
00196       {
00197          mSecurityAttributes.reset();
00198       }
00199    }
00200 
00201    for(std::vector<MessageDecorator*>::const_iterator i=rhs.mOutboundDecorators.begin(); i!=rhs.mOutboundDecorators.end();++i)
00202    {
00203       mOutboundDecorators.push_back((*i)->clone());
00204    }
00205 }
00206 
00207 void
00208 SipMessage::freeMem(bool leaveResponseStuff)
00209 {
00210    for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
00211         i != mUnknownHeaders.end(); i++)
00212    {
00213       freeHfvl(i->second);
00214    }
00215 
00216    if(!leaveResponseStuff)
00217    {
00218       for (TypedHeaders::iterator i = mHeaders.begin();
00219            i != mHeaders.end(); i++)
00220       {
00221          freeHfvl(*i);
00222       }
00223       mHeaders.clear();
00224 
00225       for (vector<char*>::iterator i = mBufferList.begin();
00226            i != mBufferList.end(); i++)
00227       {
00228          delete [] *i;
00229       }
00230    }
00231 
00232    if(mStartLine)
00233    {
00234       mStartLine->~StartLine();
00235       mStartLine=0;
00236    }
00237 
00238    delete mContents;
00239    delete mForceTarget;
00240    delete mReason;
00241 
00242    for(std::vector<MessageDecorator*>::iterator i=mOutboundDecorators.begin();
00243          i!=mOutboundDecorators.end();++i)
00244    {
00245       delete *i;
00246    }
00247 }
00248 
00249 SipMessage*
00250 SipMessage::make(const Data& data,  bool isExternal)
00251 {
00252    Transport* external = (Transport*)(0xFFFF);
00253    SipMessage* msg = new SipMessage(isExternal ? external : 0);
00254 
00255    size_t len = data.size();
00256    char *buffer = new char[len + 5];
00257 
00258    msg->addBuffer(buffer);
00259    memcpy(buffer,data.data(), len);
00260    MsgHeaderScanner msgHeaderScanner;
00261    msgHeaderScanner.prepareForMessage(msg);
00262    
00263    char *unprocessedCharPtr;
00264    if (msgHeaderScanner.scanChunk(buffer, (unsigned int)len, &unprocessedCharPtr) != MsgHeaderScanner::scrEnd)
00265    {
00266       DebugLog(<<"Scanner rejecting buffer as unparsable / fragmented.");
00267       DebugLog(<< data);
00268       delete msg; 
00269       msg = 0; 
00270       return 0;
00271    }
00272 
00273    // no pp error
00274    unsigned int used = (unsigned int)(unprocessedCharPtr - buffer);
00275 
00276    if (used < len)
00277    {
00278       // body is present .. add it up.
00279       // NB. The Sip Message uses an overlay (again)
00280       // for the body. It ALSO expects that the body
00281       // will be contiguous (of course).
00282       // it doesn't need a new buffer in UDP b/c there
00283       // will only be one datagram per buffer. (1:1 strict)
00284 
00285       msg->setBody(buffer+used,UInt32(len-used));
00286       //DebugLog(<<"added " << len-used << " byte body");
00287    }
00288 
00289    return msg;
00290 }
00291 
00292 void
00293 SipMessage::parseAllHeaders()
00294 {
00295    for (int i = 0; i < Headers::MAX_HEADERS; i++)
00296    {
00297       ParserContainerBase* pc=0;
00298       if(mHeaderIndices[i]>0)
00299       {
00300          HeaderFieldValueList* hfvl = ensureHeaders((Headers::Type)i);
00301          if(!Headers::isMulti((Headers::Type)i) && hfvl->parsedEmpty())
00302          {
00303             hfvl->push_back(0,0,false);
00304          }
00305 
00306          if(!(pc=hfvl->getParserContainer()))
00307          {
00308             pc = HeaderBase::getInstance((Headers::Type)i)->makeContainer(hfvl);
00309             hfvl->setParserContainer(pc);
00310          }
00311       
00312          pc->parseAll();
00313       }
00314    }
00315 
00316    for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
00317         i != mUnknownHeaders.end(); i++)
00318    {
00319       ParserContainerBase* scs=0;
00320       if(!(scs=i->second->getParserContainer()))
00321       {
00322          scs=makeParserContainer<StringCategory>(i->second,Headers::RESIP_DO_NOT_USE);
00323          i->second->setParserContainer(scs);
00324       }
00325       
00326       scs->parseAll();
00327    }
00328    
00329    assert(mStartLine);
00330 
00331    mStartLine->checkParsed();
00332    
00333    getContents();
00334 }
00335 
00336 const Data& 
00337 SipMessage::getTransactionId() const
00338 {
00339    if (empty(h_Vias))
00340    {
00341       InfoLog (<< "Bad message with no Vias: " << *this);
00342       throw Exception("No Via in message", __FILE__,__LINE__);
00343    }
00344    
00345    assert(exists(h_Vias) && !header(h_Vias).empty());
00346    if( exists(h_Vias) && header(h_Vias).front().exists(p_branch) 
00347        && header(h_Vias).front().param(p_branch).hasMagicCookie() 
00348        && (!header(h_Vias).front().param(p_branch).getTransactionId().empty())
00349      )
00350    {
00351       return header(h_Vias).front().param(p_branch).getTransactionId();
00352    }
00353    else
00354    {
00355       if (mRFC2543TransactionId.empty())
00356       {
00357          compute2543TransactionHash();
00358       }
00359       return mRFC2543TransactionId;
00360    }
00361 }
00362 
00363 void
00364 SipMessage::compute2543TransactionHash() const
00365 {
00366    assert (mRFC2543TransactionId.empty());
00367    
00368    /*  From rfc3261, 17.2.3
00369        The INVITE request matches a transaction if the Request-URI, To tag,
00370        From tag, Call-ID, CSeq, and top Via header field match those of the
00371        INVITE request which created the transaction.  In this case, the
00372        INVITE is a retransmission of the original one that created the
00373        transaction.  
00374 
00375        The ACK request matches a transaction if the Request-URI, From tag,
00376        Call-ID, CSeq number (not the method), and top Via header field match
00377        those of the INVITE request which created the transaction, and the To
00378        tag of the ACK matches the To tag of the response sent by the server
00379        transaction.  
00380 
00381        Matching is done based on the matching rules defined for each of those
00382        header fields.  Inclusion of the tag in the To header field in the ACK
00383        matching process helps disambiguate ACK for 2xx from ACK for other
00384        responses at a proxy, which may have forwarded both responses (This
00385        can occur in unusual conditions.  Specifically, when a proxy forked a
00386        request, and then crashes, the responses may be delivered to another
00387        proxy, which might end up forwarding multiple responses upstream).  An
00388        ACK request that matches an INVITE transaction matched by a previous
00389        ACK is considered a retransmission of that previous ACK.
00390 
00391        For all other request methods, a request is matched to a transaction
00392        if the Request-URI, To tag, From tag, Call-ID, CSeq (including the
00393        method), and top Via header field match those of the request that
00394        created the transaction.  Matching is done based on the matching
00395    */
00396 
00397    // If it is here and isn't a request, leave the transactionId empty, this
00398    // will cause the Transaction to send it statelessly
00399 
00400    if (isRequest())
00401    {
00402       MD5Stream strm;
00403       // See section 17.2.3 Matching Requests to Server Transactions in rfc 3261
00404 
00405 //#define VONAGE_FIX
00406 #ifndef VONAGE_FIX         
00407       strm << header(h_RequestLine).uri().scheme();
00408       strm << header(h_RequestLine).uri().user();
00409       strm << header(h_RequestLine).uri().host();
00410       strm << header(h_RequestLine).uri().port();
00411       strm << header(h_RequestLine).uri().password();
00412       strm << header(h_RequestLine).uri().commutativeParameterHash();
00413 #endif
00414       if (!empty(h_Vias))
00415       {
00416          strm << header(h_Vias).front().protocolName();
00417          strm << header(h_Vias).front().protocolVersion();
00418          strm << header(h_Vias).front().transport();
00419          strm << header(h_Vias).front().sentHost();
00420          strm << header(h_Vias).front().sentPort();
00421          strm << header(h_Vias).front().commutativeParameterHash();
00422       }
00423          
00424       if (header(h_From).exists(p_tag))
00425       {
00426          strm << header(h_From).param(p_tag);
00427       }
00428 
00429       // Only include the totag for non-invite requests
00430       if (header(h_RequestLine).getMethod() != INVITE && 
00431           header(h_RequestLine).getMethod() != ACK && 
00432           header(h_RequestLine).getMethod() != CANCEL &&
00433           header(h_To).exists(p_tag))
00434       {
00435          strm << header(h_To).param(p_tag);
00436       }
00437 
00438       strm << header(h_CallID).value();
00439 
00440       if (header(h_RequestLine).getMethod() == ACK || 
00441           header(h_RequestLine).getMethod() == CANCEL)
00442       {
00443          strm << INVITE;
00444          strm << header(h_CSeq).sequence();
00445       }
00446       else
00447       {
00448          strm << header(h_CSeq).method();
00449          strm << header(h_CSeq).sequence();
00450       }
00451            
00452       mRFC2543TransactionId = strm.getHex();
00453    }
00454    else
00455    {
00456       InfoLog (<< "Trying to compute a transaction id on a 2543 response. Drop the response");
00457       DebugLog (<< *this);
00458       throw Exception("Drop invalid 2543 response", __FILE__, __LINE__);
00459    }
00460 }
00461 
00462 const Data&
00463 SipMessage::getRFC2543TransactionId() const
00464 {
00465    if(empty(h_Vias) ||
00466       !header(h_Vias).front().exists(p_branch) ||
00467       !header(h_Vias).front().param(p_branch).hasMagicCookie() ||
00468       header(h_Vias).front().param(p_branch).getTransactionId().empty())
00469    {
00470       if (mRFC2543TransactionId.empty())
00471       {
00472          compute2543TransactionHash();
00473       }
00474    }
00475    return mRFC2543TransactionId;
00476 }
00477 
00478 
00479 Data
00480 SipMessage::getCanonicalIdentityString() const
00481 {
00482    Data result;
00483    DataStream strm(result);
00484    
00485    // digest-string = addr-spec ":" addr-spec ":" callid ":" 1*DIGIT SP method ":"
00486    //             SIP-Date ":" [ addr-spec ] ":" message-body
00487   
00488    strm << header(h_From).uri();
00489    strm << Symbols::BAR;
00490    
00491    strm << header(h_To).uri();
00492    strm << Symbols::BAR;
00493    
00494    strm << header(h_CallId).value();
00495    strm << Symbols::BAR;
00496    
00497    header(h_CSeq).sequence(); // force parsed
00498    header(h_CSeq).encodeParsed( strm );
00499    strm << Symbols::BAR;
00500    
00501    // if there is no date, it will throw 
00502    if ( empty(h_Date) )
00503    {
00504       WarningLog( << "Computing Identity on message with no Date header" );
00505       // TODO FIX - should it have a throw here ???? Help ???
00506    }
00507    header(h_Date).dayOfMonth(); // force it to be parsed 
00508    header(h_Date).encodeParsed( strm );
00509    strm << Symbols::BAR;
00510    
00511    if ( !empty(h_Contacts) )
00512    { 
00513       if ( header(h_Contacts).front().isAllContacts() )
00514       {
00515          strm << Symbols::STAR;
00516       }
00517       else
00518       {
00519          strm << header(h_Contacts).front().uri();
00520       }
00521    }
00522    strm << Symbols::BAR;
00523    
00524    // bodies 
00525    if (mContents != 0)
00526    {
00527       mContents->encode(strm);
00528    }
00529    else if (mContentsHfv.getBuffer() != 0)
00530    {
00531       mContentsHfv.encode(strm);
00532    }
00533 
00534    strm.flush();
00535 
00536    DebugLog( << "Indentity Canonical String is: " << result );
00537    
00538    return result;
00539 }
00540 
00541 
00542 void
00543 SipMessage::setRFC2543TransactionId(const Data& tid)
00544 {
00545    mRFC2543TransactionId = tid;
00546 }
00547 
00548 resip::MethodTypes
00549 SipMessage::method() const
00550 {
00551    resip::MethodTypes res=UNKNOWN;
00552    try
00553    {
00554       if(isRequest())
00555       {
00556          res=header(h_RequestLine).getMethod();
00557       }
00558       else if(isResponse())
00559       {
00560          res=header(h_CSeq).method();
00561       }
00562       else
00563       {
00564          assert(0);
00565       }
00566    }
00567    catch(resip::ParseException&)
00568    {
00569    }
00570    
00571    return res;
00572 }
00573 
00574 const Data&
00575 SipMessage::methodStr() const
00576 {
00577    if(method()!=UNKNOWN)
00578    {
00579       return getMethodName(method());
00580    }
00581    else
00582    {
00583       try
00584       {
00585          if(isRequest())
00586          {
00587             return header(h_RequestLine).unknownMethodName();
00588          }
00589          else if(isResponse())
00590          {
00591             return header(h_CSeq).unknownMethodName();
00592          }
00593          else
00594          {
00595             assert(0);
00596          }
00597       }
00598       catch(resip::ParseException&)
00599       {
00600       }
00601    }
00602    return Data::Empty;
00603 }
00604 
00605 static const Data requestEB("SipReq:  ");
00606 static const Data responseEB("SipResp: ");
00607 static const Data tidEB(" tid=");
00608 static const Data contactEB(" contact=");
00609 static const Data cseqEB(" cseq=");
00610 static const Data slashEB(" / ");
00611 static const Data wireEB(" from(wire)");
00612 static const Data ftuEB(" from(tu)");
00613 static const Data tlsdEB(" tlsd=");
00614 EncodeStream&
00615 SipMessage::encodeBrief(EncodeStream& str) const
00616 {
00617    if (isRequest()) 
00618    {
00619       str << requestEB;
00620       MethodTypes meth = header(h_RequestLine).getMethod();
00621       if (meth != UNKNOWN)
00622       {
00623          str << getMethodName(meth);
00624       }
00625       else
00626       {
00627          str << header(h_RequestLine).unknownMethodName();
00628       }
00629       
00630       str << Symbols::SPACE;
00631       str << header(h_RequestLine).uri().getAor();
00632    }
00633    else if (isResponse())
00634    {
00635       str << responseEB;
00636       str << header(h_StatusLine).responseCode();
00637    }
00638    if (!empty(h_Vias))
00639    {
00640       str << tidEB;
00641       try
00642       {
00643          str << getTransactionId();
00644       }
00645       catch(SipMessage::Exception&)
00646       {
00647          str << "BAD-VIA";
00648       }
00649    }
00650    else
00651    {
00652       str << " NO-VIAS ";
00653    }
00654 
00655    str << cseqEB;
00656    str << header(h_CSeq);
00657 
00658    try
00659    {
00660       if (!empty(h_Contacts))
00661       {
00662          str << contactEB;
00663          str << header(h_Contacts).front().uri().getAor();
00664       }
00665    }
00666    catch(resip::ParseException&)
00667    {
00668       str << " MALFORMED CONTACT ";
00669    }
00670    
00671    str << slashEB;
00672    str << header(h_CSeq).sequence();
00673    str << (mIsExternal ? wireEB : ftuEB);
00674    if (!mTlsDomain.empty())
00675    {
00676       str << tlsdEB << mTlsDomain;
00677    }
00678    
00679    return str;
00680 }
00681 
00682 bool
00683 SipMessage::isClientTransaction() const
00684 {
00685    assert(mRequest || mResponse);
00686    return ((mIsExternal && mResponse) || (!mIsExternal && mRequest));
00687 }
00688 
00689 EncodeStream&
00690 SipMessage::encode(EncodeStream& str) const
00691 {
00692    return encode(str, false);
00693 }
00694 
00695 EncodeStream&
00696 SipMessage::encodeSipFrag(EncodeStream& str) const
00697 {
00698    return encode(str, true);
00699 }
00700 
00701 // dynamic_cast &str to DataStream* to avoid CountStream?
00702 
00703 EncodeStream&
00704 SipMessage::encode(EncodeStream& str, bool isSipFrag) const
00705 {
00706    if (mStartLine != 0)
00707    {
00708       mStartLine->encode(str);
00709       str << "\r\n";
00710    }
00711 
00712    Data contents;
00713    if (mContents != 0)
00714    {
00715       oDataStream temp(contents);
00716       mContents->encode(temp);
00717    }
00718    else if (mContentsHfv.getBuffer() != 0)
00719    {
00720 #if 0
00721       // !bwc! This causes an additional copy; sure would be nice to have a way
00722       // to get a data to take on a buffer with Data::Share _after_ construction
00723       contents.append(mContentsHfv.getBuffer(), mContentsHfv.getLength());
00724 #else
00725       // .kw. Your wish is granted
00726       mContentsHfv.toShareData(contents);
00727 #endif
00728    }
00729 
00730    for (UInt8 i = 0; i < Headers::MAX_HEADERS; i++)
00731    {
00732       if (i != Headers::ContentLength) // !dlb! hack...
00733       {
00734          if (mHeaderIndices[i] > 0)
00735          {
00736             mHeaders[mHeaderIndices[i]]->encode(i, str);
00737          }
00738       }
00739    }
00740 
00741    for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); 
00742         i != mUnknownHeaders.end(); i++)
00743    {
00744       i->second->encode(i->first, str);
00745    }
00746 
00747    if(!isSipFrag || !contents.empty())
00748    {
00749       str << "Content-Length: " << contents.size() << "\r\n";
00750    }
00751 
00752    str << Symbols::CRLF;
00753    
00754    str << contents;
00755    return str;
00756 }
00757 
00758 EncodeStream&
00759 SipMessage::encodeSingleHeader(Headers::Type type, EncodeStream& str) const
00760 {
00761    if (mHeaderIndices[type] > 0)
00762    {
00763       mHeaders[mHeaderIndices[type]]->encode(type, str);
00764    }
00765    return str;
00766 }
00767 
00768 EncodeStream& 
00769 SipMessage::encodeEmbedded(EncodeStream& str) const
00770 {
00771    bool first = true;
00772    for (UInt8 i = 0; i < Headers::MAX_HEADERS; i++)
00773    {
00774       if (i != Headers::ContentLength)
00775       {
00776          if (mHeaderIndices[i] > 0)
00777          {
00778             if (first)
00779             {
00780                str << Symbols::QUESTION;
00781                first = false;
00782             }
00783             else
00784             {
00785                str << Symbols::AMPERSAND;
00786             }
00787             mHeaders[mHeaderIndices[i]]->encodeEmbedded(Headers::getHeaderName(i), str);
00788          }
00789       }
00790    }
00791 
00792    for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); 
00793         i != mUnknownHeaders.end(); i++)
00794    {
00795       if (first)
00796       {
00797          str << Symbols::QUESTION;
00798          first = false;
00799       }
00800       else
00801       {
00802          str << Symbols::AMPERSAND;
00803       }
00804       i->second->encodeEmbedded(i->first, str);
00805    }
00806 
00807    if (mContents != 0 || mContentsHfv.getBuffer() != 0)
00808    {
00809       if (first)
00810       {
00811          str << Symbols::QUESTION;
00812       }
00813       else
00814       {
00815          str << Symbols::AMPERSAND;
00816       }
00817       str << "body=";
00818       Data contents;
00819       // !dlb! encode escaped for characters
00820       // .kw. what does that mean? what needs to be escaped?
00821       if(mContents != 0)
00822       {
00823          DataStream s(contents);
00824          mContents->encode(s);
00825       }
00826       else
00827       {
00828          // .kw. Early code did:
00829          // DataStream s(contents);
00830          // mContentsHfv->encode(str);
00831          // str << Embedded::encode(contents);
00832          // .kw. which I think is buggy b/c Hfv was written directly
00833          // to str and skipped the encode step via contents
00834          mContentsHfv.toShareData(contents);
00835       }
00836       str << Embedded::encode(contents);
00837    }
00838    return str;
00839 }
00840 
00841 void
00842 SipMessage::addBuffer(char* buf)
00843 {
00844    mBufferList.push_back(buf);
00845 }
00846 
00847 void 
00848 SipMessage::setStartLine(const char* st, int len)
00849 {
00850    if(len >= 4 && !strncasecmp(st,"SIP/",4))
00851    {
00852       // Response
00853       mStartLine = new (mStartLineMem) StatusLine(st, len);
00855       mResponse = true;
00856    }
00857    else
00858    {
00859       // Request
00860       mStartLine = new (mStartLineMem) RequestLine(st, len);
00862       mRequest = true;
00863    }
00864 
00865 
00866 // .bwc. This stuff is so needlessly complicated. Much, much simpler, faster,
00867 // and more robust code above.
00868 //   ParseBuffer pb(st, len);
00869 //   const char* start;
00870 //   start = pb.skipWhitespace();
00871 //   pb.skipNonWhitespace();
00872 //   MethodTypes method = getMethodType(start, pb.position() - start);
00873 //   if (method == UNKNOWN) //probably a status line
00874 //   {
00875 //      start = pb.skipChar(Symbols::SPACE[0]);
00876 //      pb.skipNonWhitespace();
00877 //      if ((pb.position() - start) == 3)
00878 //      {
00879 //         mStartLine = new (mStartLineMem) StatusLine(st, len ,Headers::NONE);
00880 //         //!dcm! should invoke the statusline parser here once it does limited validation
00881 //         mResponse = true;
00882 //      }
00883 //   }
00884 //   if (!mResponse)
00885 //   {
00886 //      mStartLine = new (mStartLineMem) RequestLine(st, len, Headers::NONE);
00887 //      //!dcm! should invoke the responseline parser here once it does limited validation
00888 //      mRequest = true;
00889 //   }
00890 }
00891 
00892 void 
00893 SipMessage::setBody(const char* start, UInt32 len)
00894 {
00895    if(checkContentLength)
00896    {
00897       if(exists(h_ContentLength))
00898       {
00899          try
00900          {
00901             const_header(h_ContentLength).checkParsed();
00902          }
00903          catch(resip::ParseException& e)
00904          {
00905             if(!mReason)
00906             {
00907                mReason=new Data;
00908             }
00909             
00910             if(mInvalid)
00911             {
00912                mReason->append(",",1);
00913             }
00914 
00915             mInvalid=true; 
00916             mReason->append("Malformed Content-Length",24);
00917             InfoLog(<< "Malformed Content-Length. Ignoring. " << e);
00918             header(h_ContentLength).value()=len;
00919          }
00920          
00921          UInt32 contentLength=const_header(h_ContentLength).value();
00922          
00923          if(len > contentLength)
00924          {
00925             InfoLog(<< (len-contentLength) << " extra bytes after body. Ignoring these bytes.");
00926          }
00927          else if(len < contentLength)
00928          {
00929             InfoLog(<< "Content Length (" << contentLength << ") is "
00930                     << (contentLength-len) << " bytes larger than body (" << len << ")!"
00931                     << " (We are supposed to 400 this) ");
00932 
00933             if(!mReason)
00934             {
00935                mReason=new Data;
00936             }
00937 
00938             if(mInvalid)
00939             {
00940                mReason->append(",",1);
00941             }
00942 
00943             mInvalid=true; 
00944             mReason->append("Bad Content-Length (larger than datagram)",41);
00945             header(h_ContentLength).value()=len;
00946             contentLength=len;
00947                      
00948          }
00949          
00950          mContentsHfv.init(start,contentLength, false);
00951       }
00952       else
00953       {
00954          InfoLog(<< "Message has a body, but no Content-Length header.");
00955          mContentsHfv.init(start,len, false);
00956       }
00957    }
00958    else
00959    {
00960       mContentsHfv.init(start,len, false);
00961    }
00962 }
00963 
00964 void
00965 SipMessage::setRawBody(const HeaderFieldValue& body)
00966 {
00967    setContents(0);
00968    mContentsHfv = body;
00969 }
00970 
00971 
00972 void
00973 SipMessage::setContents(auto_ptr<Contents> contents)
00974 {
00975    Contents* contentsP = contents.release();
00976 
00977    delete mContents;
00978    mContents = 0;
00979    mContentsHfv.clear();
00980 
00981    if (contentsP == 0)
00982    {
00983       // The semantics of setContents(0) are to delete message contents
00984       remove(h_ContentType);
00985       remove(h_ContentDisposition);
00986       remove(h_ContentTransferEncoding);
00987       remove(h_ContentLanguages);
00988       return;
00989    }
00990 
00991    mContents = contentsP;
00992 
00993    // copy contents headers into message
00994    if (mContents->exists(h_ContentDisposition))
00995    {
00996       header(h_ContentDisposition) = mContents->header(h_ContentDisposition);
00997    }
00998    if (mContents->exists(h_ContentTransferEncoding))
00999    {
01000       header(h_ContentTransferEncoding) = mContents->header(h_ContentTransferEncoding);
01001    }
01002    if (mContents->exists(h_ContentLanguages))
01003    {
01004       header(h_ContentLanguages) = mContents->header(h_ContentLanguages);
01005    }
01006    if (mContents->exists(h_ContentType))
01007    {
01008       header(h_ContentType) = mContents->header(h_ContentType);
01009       assert( header(h_ContentType).type() == mContents->getType().type() );
01010       assert( header(h_ContentType).subType() == mContents->getType().subType() );
01011    }
01012    else
01013    {
01014       header(h_ContentType) = mContents->getType();
01015    }
01016 }
01017 
01018 void 
01019 SipMessage::setContents(const Contents* contents)
01020 { 
01021    if (contents)
01022    {
01023       setContents(auto_ptr<Contents>(contents->clone()));
01024    }
01025    else
01026    {
01027       setContents(auto_ptr<Contents>(0));
01028    }
01029 }
01030 
01031 Contents*
01032 SipMessage::getContents() const
01033 {
01034    if (mContents == 0 && mContentsHfv.getBuffer() != 0)
01035    {
01036       if (empty(h_ContentType) ||
01037             !const_header(h_ContentType).isWellFormed())
01038       {
01039          StackLog(<< "SipMessage::getContents: ContentType header does not exist - implies no contents");
01040          return 0;
01041       }
01042       DebugLog(<< "SipMessage::getContents: " 
01043                << const_header(h_ContentType).type()
01044                << "/"
01045                << const_header(h_ContentType).subType());
01046 
01047       if ( ContentsFactoryBase::getFactoryMap().find(const_header(h_ContentType)) == ContentsFactoryBase::getFactoryMap().end() )
01048       {
01049          InfoLog(<< "SipMessage::getContents: got content type ("
01050                  << const_header(h_ContentType).type()
01051                  << "/"
01052                  << const_header(h_ContentType).subType()
01053                  << ") that is not known, "
01054                  << "returning as opaque application/octet-stream");
01055          mContents = ContentsFactoryBase::getFactoryMap()[OctetContents::getStaticType()]->create(mContentsHfv, OctetContents::getStaticType());
01056       }
01057       else
01058       {
01059          mContents = ContentsFactoryBase::getFactoryMap()[const_header(h_ContentType)]->create(mContentsHfv, const_header(h_ContentType));
01060       }
01061       assert( mContents );
01062       
01063       // copy contents headers into the contents
01064       if (!empty(h_ContentDisposition))
01065       {
01066          mContents->header(h_ContentDisposition) = const_header(h_ContentDisposition);
01067       }
01068       if (!empty(h_ContentTransferEncoding))
01069       {
01070          mContents->header(h_ContentTransferEncoding) = const_header(h_ContentTransferEncoding);
01071       }
01072       if (!empty(h_ContentLanguages))
01073       {
01074          mContents->header(h_ContentLanguages) = const_header(h_ContentLanguages);
01075       }
01076       if (!empty(h_ContentType))
01077       {
01078          mContents->header(h_ContentType) = const_header(h_ContentType);
01079       }
01080       // !dlb! Content-Transfer-Encoding?
01081    }
01082    return mContents;
01083 }
01084 
01085 auto_ptr<Contents>
01086 SipMessage::releaseContents()
01087 {
01088    Contents* c=getContents();
01089    // .bwc. auto_ptr owns the Contents. No other references allowed!
01090    auto_ptr<Contents> ret(c ? c->clone() : 0);
01091    setContents(std::auto_ptr<Contents>(0));
01092 
01093    if (ret.get() != 0 && !ret->isWellFormed())
01094    {
01095       ret.reset(0);
01096    }
01097 
01098    return ret;
01099 }
01100 
01101 // unknown header interface
01102 const StringCategories& 
01103 SipMessage::header(const ExtensionHeader& headerName) const
01104 {
01105    for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin();
01106         i != mUnknownHeaders.end(); i++)
01107    {      
01108       if (isEqualNoCase(i->first, headerName.getName()))
01109       {
01110          HeaderFieldValueList* hfvs = i->second;
01111          if (hfvs->getParserContainer() == 0)
01112          {
01113             SipMessage* nc_this(const_cast<SipMessage*>(this));
01114             hfvs->setParserContainer(nc_this->makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
01115          }
01116          return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
01117       }
01118    }
01119    // missing extension header
01120    assert(false);
01121 
01122    return *(StringCategories*)0;
01123 }
01124 
01125 StringCategories& 
01126 SipMessage::header(const ExtensionHeader& headerName)
01127 {
01128    for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
01129         i != mUnknownHeaders.end(); i++)
01130    {
01131       if (isEqualNoCase(i->first, headerName.getName()))
01132       {
01133          HeaderFieldValueList* hfvs = i->second;
01134          if (hfvs->getParserContainer() == 0)
01135          {
01136             hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
01137          }
01138          return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
01139       }
01140    }
01141 
01142    // create the list empty
01143    HeaderFieldValueList* hfvs = getEmptyHfvl();
01144    hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
01145    mUnknownHeaders.push_back(make_pair(headerName.getName(), hfvs));
01146    return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
01147 }
01148 
01149 bool
01150 SipMessage::exists(const ExtensionHeader& symbol) const
01151 {
01152    for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin();
01153         i != mUnknownHeaders.end(); i++)
01154    {
01155       if (isEqualNoCase(i->first, symbol.getName()))
01156       {
01157          return true;
01158       }
01159    }
01160    return false;
01161 }
01162 
01163 void
01164 SipMessage::remove(const ExtensionHeader& headerName)
01165 {
01166    for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
01167         i != mUnknownHeaders.end(); i++)
01168    {
01169       if (isEqualNoCase(i->first, headerName.getName()))
01170       {
01171          freeHfvl(i->second);
01172          mUnknownHeaders.erase(i);
01173          return;
01174       }
01175    }
01176 }
01177 
01178 void
01179 SipMessage::addHeader(Headers::Type header, const char* headerName, int headerLen, 
01180                       const char* start, int len)
01181 {
01182    if (header != Headers::UNKNOWN)
01183    {
01184       HeaderFieldValueList* hfvl=0;
01185       if (mHeaderIndices[header] == 0)
01186       {
01187          mHeaderIndices[header] = mHeaders.size();
01188          mHeaders.push_back(getEmptyHfvl());
01189          hfvl=mHeaders.back();
01190       }
01191       else
01192       {
01193          if(mHeaderIndices[header]<0)
01194          {
01195             // Adding to a previously removed header type; there is already an 
01196             // empty HeaderFieldValueList in mHeaders for this type, all we 
01197             // need to do is flip the sign to re-enable it.
01198             mHeaderIndices[header] *= -1;
01199          }
01200          hfvl=mHeaders[mHeaderIndices[header]];
01201       }
01202 
01203       if(Headers::isMulti(header))
01204       {
01205          if (len)
01206          {
01207             hfvl->push_back(start, len, false);
01208          }
01209       }
01210       else
01211       {
01212          if(hfvl->size()==1)
01213          {
01214             if(!mReason)
01215             {
01216                mReason=new Data;
01217             }
01218             
01219             if(mInvalid)
01220             {
01221                mReason->append(",",1);
01222             }
01223             mInvalid=true;
01224             mReason->append("Multiple values in single-value header ",39);
01225             (*mReason)+=Headers::getHeaderName(header);
01226             return;
01227          }
01228          hfvl->push_back(start ? start : Data::Empty.data(), len, false);
01229       }
01230 
01231    }
01232    else
01233    {
01234       assert(headerLen >= 0);
01235       for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
01236            i != mUnknownHeaders.end(); i++)
01237       {
01238          if (i->first.size() == (unsigned int)headerLen &&
01239              strncasecmp(i->first.data(), headerName, headerLen) == 0)
01240          {
01241             // add to end of list
01242             if (len)
01243             {
01244                i->second->push_back(start, len, false);
01245             }
01246             return;
01247          }
01248       }
01249 
01250       // didn't find it, add an entry
01251       HeaderFieldValueList *hfvs = getEmptyHfvl();
01252       if (len)
01253       {
01254          hfvs->push_back(start, len, false);
01255       }
01256       mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(Data(headerName, headerLen),
01257                                                                   hfvs));
01258    }
01259 }
01260 
01261 RequestLine& 
01262 SipMessage::header(const RequestLineType& l)
01263 {
01264    assert (!isResponse());
01265    if (mStartLine == 0 )
01266    { 
01267       mStartLine = new (mStartLineMem) RequestLine;
01268       mRequest = true;
01269    }
01270    return *static_cast<RequestLine*>(mStartLine);
01271 }
01272 
01273 const RequestLine& 
01274 SipMessage::header(const RequestLineType& l) const
01275 {
01276    assert (!isResponse());
01277    if (mStartLine == 0 )
01278    { 
01279       // request line missing
01280       assert(false);
01281    }
01282    return *static_cast<RequestLine*>(mStartLine);
01283 }
01284 
01285 StatusLine& 
01286 SipMessage::header(const StatusLineType& l)
01287 {
01288    assert (!isRequest());
01289    if (mStartLine == 0 )
01290    { 
01291       mStartLine = new (mStartLineMem) StatusLine;
01292       mResponse = true;
01293    }
01294    return *static_cast<StatusLine*>(mStartLine);
01295 }
01296 
01297 const StatusLine& 
01298 SipMessage::header(const StatusLineType& l) const
01299 {
01300    assert (!isRequest());
01301    if (mStartLine == 0 )
01302    { 
01303       // status line missing
01304       assert(false);
01305    }
01306    return *static_cast<StatusLine*>(mStartLine);
01307 }
01308 
01309 HeaderFieldValueList* 
01310 SipMessage::ensureHeaders(Headers::Type type)
01311 {
01312    HeaderFieldValueList* hfvl=0;
01313    if(mHeaderIndices[type]!=0)
01314    {
01315       if(mHeaderIndices[type]<0)
01316       {
01317          // Accessing a previously removed header type; there is already an 
01318          // empty HeaderFieldValueList in mHeaders for this type, all we 
01319          // need to do is flip the sign to re-enable it.
01320          mHeaderIndices[type] *= -1;
01321       }
01322       hfvl = mHeaders[mHeaderIndices[type]];
01323    }
01324    else
01325    {
01326       // create the list with a new component
01327       mHeaders.push_back(getEmptyHfvl());
01328       hfvl=mHeaders.back();
01329       mHeaderIndices[type]=mHeaders.size()-1;
01330    }
01331 
01332    return hfvl;
01333 }
01334 
01335 HeaderFieldValueList* 
01336 SipMessage::ensureHeader(Headers::Type type)
01337 {
01338    HeaderFieldValueList* hfvl=0;
01339    if(mHeaderIndices[type]!=0)
01340    {
01341       if(mHeaderIndices[type]<0)
01342       {
01343          // Accessing a previously removed header type; there is already an 
01344          // empty HeaderFieldValueList in mHeaders for this type, all we 
01345          // need to do is flip the sign to re-enable it.
01346          mHeaderIndices[type] *= -1;
01347          hfvl = mHeaders[mHeaderIndices[type]];
01348          hfvl->push_back(0,0,false);
01349       }
01350       hfvl = mHeaders[mHeaderIndices[type]];
01351    }
01352    else
01353    {
01354       // create the list with a new component
01355       mHeaders.push_back(getEmptyHfvl());
01356       hfvl=mHeaders.back();
01357       mHeaderIndices[type]=mHeaders.size()-1;
01358       mHeaders.back()->push_back(0,0,false);
01359    }
01360 
01361    return hfvl;
01362 }
01363 
01364 void
01365 SipMessage::throwHeaderMissing(Headers::Type type) const
01366 {
01367    // header missing
01368    // assert(false);
01369    InfoLog( << "Missing Header [" << Headers::getHeaderName(type) << "]");      
01370    DebugLog (<< *this);
01371    throw Exception("Missing header " + Headers::getHeaderName(type), __FILE__, __LINE__);
01372 }
01373 
01374 // type safe header accessors
01375 bool    
01376 SipMessage::exists(const HeaderBase& headerType) const 
01377 {
01378    return mHeaderIndices[headerType.getTypeNum()] > 0;
01379 };
01380 
01381 bool
01382 SipMessage::empty(const HeaderBase& headerType) const
01383 {
01384    return (mHeaderIndices[headerType.getTypeNum()] <= 0) || mHeaders[mHeaderIndices[headerType.getTypeNum()]]->parsedEmpty();
01385 }
01386 
01387 void
01388 SipMessage::remove(Headers::Type type)
01389 {
01390    if(mHeaderIndices[type] > 0)
01391    {
01392       // .bwc. The entry in mHeaders still remains after we do this; we retain 
01393       // our index (as a negative number, indicating that this header should 
01394       // not be encoded), in case this header type needs to be used later.
01395       mHeaders[mHeaderIndices[type]]->clear();
01396       mHeaderIndices[type] *= -1;
01397    }
01398 };
01399 
01400 #ifndef PARTIAL_TEMPLATE_SPECIALIZATION
01401 
01402 #undef defineHeader
01403 #define defineHeader(_header, _name, _type, _rfc)                                                       \
01404 const H_##_header::Type&                                                                                \
01405 SipMessage::header(const H_##_header& headerType) const                                                 \
01406 {                                                                                                       \
01407    HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
01408    if (hfvs->getParserContainer() == 0)                                                                 \
01409    {                                                                                                    \
01410       SipMessage* nc_this(const_cast<SipMessage*>(this)); \
01411       hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
01412    }                                                                                                    \
01413    return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
01414 }                                                                                                       \
01415                                                                                                         \
01416 H_##_header::Type&                                                                                      \
01417 SipMessage::header(const H_##_header& headerType)                                                       \
01418 {                                                                                                       \
01419    HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
01420    if (hfvs->getParserContainer() == 0)                                                                 \
01421    {                                                                                                    \
01422       hfvs->setParserContainer(makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
01423    }                                                                                                    \
01424    return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
01425 }
01426 
01427 #undef defineMultiHeader
01428 #define defineMultiHeader(_header, _name, _type, _rfc)                                          \
01429 const H_##_header##s::Type&                                                                     \
01430 SipMessage::header(const H_##_header##s& headerType) const                                      \
01431 {                                                                                               \
01432    HeaderFieldValueList* hfvs = ensureHeaders(headerType.getTypeNum());                  \
01433    if (hfvs->getParserContainer() == 0)                                                         \
01434    {                                                                                            \
01435       SipMessage* nc_this(const_cast<SipMessage*>(this)); \
01436       hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header##s::ContainedType>(hfvs, headerType.getTypeNum()));        \
01437    }                                                                                            \
01438    return *static_cast<H_##_header##s::Type*>(hfvs->getParserContainer());                     \
01439 }                                                                                               \
01440                                                                                                 \
01441 H_##_header##s::Type&                                                                           \
01442 SipMessage::header(const H_##_header##s& headerType)                                            \
01443 {                                                                                               \
01444    HeaderFieldValueList* hfvs = ensureHeaders(headerType.getTypeNum());                  \
01445    if (hfvs->getParserContainer() == 0)                                                         \
01446    {                                                                                            \
01447       hfvs->setParserContainer(makeParserContainer<H_##_header##s::ContainedType>(hfvs, headerType.getTypeNum()));        \
01448    }                                                                                            \
01449    return *static_cast<H_##_header##s::Type*>(hfvs->getParserContainer());                     \
01450 }
01451 
01452 defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261");
01453 defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261");
01454 defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261");
01455 defineHeader(Priority, "Priority", Token, "RFC 3261");
01456 defineHeader(Event, "Event", Token, "RFC 3265");
01457 defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265");
01458 defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903");
01459 defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903");
01460 defineHeader(ContentId, "Content-ID", Token, "RFC 2045");
01461 defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265");
01462 defineHeader(Identity, "Identity", StringCategory, "RFC 4474");
01463 defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261");
01464 defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261");
01465 defineMultiHeader(Allow, "Allow", Token, "RFC 3261");
01466 defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261");
01467 defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261");
01468 defineMultiHeader(Require, "Require", Token, "RFC 3261");
01469 defineMultiHeader(Supported, "Supported", Token, "RFC 3261");
01470 defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261");
01471 defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329");
01472 defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329");
01473 defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329");
01474 defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841");
01475 defineMultiHeader(Reason, "Reason", Token, "RFC 3326");
01476 defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323");
01477 defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313");
01478 defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488");
01479 defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01");
01480 defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01");
01481 
01482 defineMultiHeader(Accept, "Accept", Mime, "RFC 3261");
01483 defineHeader(ContentType, "Content-Type", Mime, "RFC 3261");
01484 
01485 defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261");
01486 defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261");
01487 defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261");
01488 defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474");
01489 
01490 defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261");
01491 defineMultiHeader(Route, "Route", NameAddr, "RFC 3261");
01492 defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261");
01493 defineHeader(From, "From", NameAddr, "RFC 3261");
01494 defineHeader(To, "To", NameAddr, "RFC 3261");
01495 defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261");
01496 defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515");
01497 defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892");
01498 defineMultiHeader(Path, "Path", NameAddr, "RFC 3327");
01499 defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841");
01500 defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841");
01501 defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325");
01502 defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325");
01503 defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455");
01504 defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455");
01505 defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608");
01506 
01507 defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?");
01508 defineHeader(Organization, "Organization", StringCategory, "RFC 3261");
01509 defineHeader(Server, "Server", StringCategory, "RFC 3261");
01510 defineHeader(Subject, "Subject", StringCategory, "RFC 3261");
01511 defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261");
01512 defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261");
01513 
01514 defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261");
01515 defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261");
01516 defineHeader(MinExpires, "Min-Expires", Uint32Category, "RFC 3261");
01517 defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261");
01518 
01519 // !dlb! this one is not quite right -- can have (comment) after field value
01520 defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261");
01521 defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626");
01522 
01523 defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261");
01524 defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028");
01525 defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028");
01526 
01527 defineHeader(CallID, "Call-ID", CallID, "RFC 3261");
01528 defineHeader(Replaces, "Replaces", CallID, "RFC 3891");
01529 defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261");
01530 defineHeader(Join, "Join", CallId, "RFC 3911");
01531 defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538");
01532 
01533 defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261");
01534 defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261");
01535 defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261");
01536 defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261");
01537 defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261");
01538 
01539 defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261");
01540 defineHeader(Date, "Date", DateCategory, "RFC 3261");
01541 defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261");
01542 defineMultiHeader(Via, "Via", Via, "RFC 3261");
01543 defineHeader(RAck, "RAck", RAckCategory, "RFC 3262");
01544 defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep?
01545 defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244");
01546 
01547 #endif
01548 
01549 const HeaderFieldValueList*
01550 SipMessage::getRawHeader(Headers::Type headerType) const
01551 {
01552    if(mHeaderIndices[headerType]>0)
01553    {
01554       return mHeaders[mHeaderIndices[headerType]];
01555    }
01556    
01557    return 0;
01558 }
01559 
01560 void
01561 SipMessage::setRawHeader(const HeaderFieldValueList* hfvs, Headers::Type headerType)
01562 {
01563    HeaderFieldValueList* copy=0;
01564    if (mHeaderIndices[headerType] == 0)
01565    {
01566       mHeaderIndices[headerType]=mHeaders.size();
01567       copy=getCopyHfvl(*hfvs);
01568       mHeaders.push_back(copy);
01569    }
01570    else
01571    {
01572       if(mHeaderIndices[headerType]<0)
01573       {
01574          // Setting a previously removed header type; there is already an 
01575          // empty HeaderFieldValueList in mHeaders for this type, all we 
01576          // need to do is flip the sign to re-enable it.
01577          mHeaderIndices[headerType]=-mHeaderIndices[headerType];
01578       }
01579       copy = mHeaders[mHeaderIndices[headerType]];
01580       *copy=*hfvs;
01581    }
01582    if(!Headers::isMulti(headerType) && copy->parsedEmpty())
01583    {
01584       copy->push_back(0,0,false);
01585    }
01586 }
01587 
01588 void
01589 SipMessage::setForceTarget(const Uri& uri)
01590 {
01591    if (mForceTarget)
01592    {
01593       *mForceTarget = uri;
01594    }
01595    else
01596    {
01597       mForceTarget = new Uri(uri);
01598    }
01599 }
01600 
01601 void
01602 SipMessage::clearForceTarget()
01603 {
01604    delete mForceTarget;
01605    mForceTarget = 0;
01606 }
01607 
01608 const Uri&
01609 SipMessage::getForceTarget() const
01610 {
01611    assert(mForceTarget);
01612    return *mForceTarget;
01613 }
01614 
01615 bool
01616 SipMessage::hasForceTarget() const
01617 {
01618    return (mForceTarget != 0);
01619 }
01620 
01621 SipMessage& 
01622 SipMessage::mergeUri(const Uri& source)
01623 {
01624    header(h_RequestLine).uri() = source;
01625    header(h_RequestLine).uri().removeEmbedded();
01626 
01627    if (source.exists(p_method))
01628    {
01629       header(h_RequestLine).method() = getMethodType(source.param(p_method));
01630       header(h_RequestLine).uri().remove(p_method);      
01631    }           
01632    
01633    //19.1.5
01634    //dangerous headers not included in merge:
01635    // From, Call-ID, Cseq, Via, Record Route, Route, Accept, Accept-Encoding,
01636    // Accept-Langauge, Allow, Contact, Organization, Supported, User-Agent
01637 
01638    //from the should-verify section, remove for now, some never seem to make
01639    //sense:  
01640    // Content-Encoding, Content-Language, Content-Length, Content-Type, Date,
01641    // Mime-Version, and TimeStamp
01642 
01643    if (source.hasEmbedded())
01644    {
01645       h_AuthenticationInfo.merge(*this, source.embedded());
01646       h_ContentTransferEncoding.merge(*this, source.embedded());
01647       h_Event.merge(*this, source.embedded());
01648       h_Expires.merge(*this, source.embedded());
01649       h_SessionExpires.merge(*this, source.embedded());
01650       h_MinSE.merge(*this, source.embedded());
01651       h_InReplyTo.merge(*this, source.embedded());
01652       h_MaxForwards.merge(*this, source.embedded());
01653       h_MinExpires.merge(*this, source.embedded());
01654       h_Priority.merge(*this, source.embedded());
01655       h_ReferTo.merge(*this, source.embedded());
01656       h_ReferredBy.merge(*this, source.embedded());
01657       h_Replaces.merge(*this, source.embedded());
01658       h_ReplyTo.merge(*this, source.embedded());
01659       h_RetryAfter.merge(*this, source.embedded());
01660       h_Server.merge(*this, source.embedded());
01661       h_SIPETag.merge(*this, source.embedded());
01662       h_SIPIfMatch.merge(*this, source.embedded());
01663       h_Subject.merge(*this, source.embedded());
01664       h_SubscriptionState.merge(*this, source.embedded());
01665       h_To.merge(*this, source.embedded());
01666       h_Warnings.merge(*this, source.embedded());
01667 
01668       h_SecurityClients.merge(*this, source.embedded());
01669       h_SecurityServers.merge(*this, source.embedded());
01670       h_SecurityVerifys.merge(*this, source.embedded());
01671 
01672       h_Authorizations.merge(*this, source.embedded());
01673       h_ProxyAuthenticates.merge(*this, source.embedded());
01674       h_WWWAuthenticates.merge(*this, source.embedded());
01675       h_ProxyAuthorizations.merge(*this, source.embedded());
01676 
01677       h_AlertInfos.merge(*this, source.embedded());
01678       h_AllowEvents.merge(*this, source.embedded());
01679       h_CallInfos.merge(*this, source.embedded());
01680       h_ErrorInfos.merge(*this, source.embedded());
01681       h_ProxyRequires.merge(*this, source.embedded());
01682       h_Requires.merge(*this, source.embedded());
01683       h_Unsupporteds.merge(*this, source.embedded());
01684       h_AnswerMode.merge(*this, source.embedded());
01685       h_PrivAnswerMode.merge(*this, source.embedded());
01686 
01687       h_RSeq.merge(*this, source.embedded());
01688       h_RAck.merge(*this, source.embedded());
01689    }   
01690    //unknown header merge
01691    return *this;   
01692 }
01693 
01694 void 
01695 SipMessage::setSecurityAttributes(auto_ptr<SecurityAttributes> sec)
01696 {
01697    mSecurityAttributes = sec;
01698 }
01699 
01700 void
01701 SipMessage::callOutboundDecorators(const Tuple &src, 
01702                                     const Tuple &dest,
01703                                     const Data& sigcompId)
01704 {
01705    if(mIsDecorated)
01706    {
01707       rollbackOutboundDecorators();
01708    }
01709 
01710   std::vector<MessageDecorator*>::iterator i;
01711   for (i = mOutboundDecorators.begin();
01712        i != mOutboundDecorators.end(); i++)
01713   {
01714     (*i)->decorateMessage(*this, src, dest, sigcompId);
01715   }
01716   mIsDecorated = true;
01717 }
01718 
01719 void 
01720 SipMessage::clearOutboundDecorators()
01721 {
01722    while(!mOutboundDecorators.empty())
01723    {
01724       delete mOutboundDecorators.back();
01725       mOutboundDecorators.pop_back();
01726    }
01727 }
01728 
01729 void 
01730 SipMessage::rollbackOutboundDecorators()
01731 {
01732    std::vector<MessageDecorator*>::reverse_iterator r;
01733    for(r=mOutboundDecorators.rbegin(); r!=mOutboundDecorators.rend(); ++r)
01734    {
01735       (*r)->rollbackMessage(*this);
01736    }
01737    mIsDecorated = false;
01738 }
01739 
01740 void 
01741 SipMessage::copyOutboundDecoratorsToStackCancel(SipMessage& cancel)
01742 {
01743   std::vector<MessageDecorator*>::iterator i;
01744   for (i = mOutboundDecorators.begin();
01745        i != mOutboundDecorators.end(); i++)
01746   {
01747      if((*i)->copyToStackCancels())
01748      {
01749         cancel.addOutboundDecorator(*(new auto_ptr<MessageDecorator>((*i)->clone())));
01750      }    
01751   }
01752 }
01753 
01754 void 
01755 SipMessage::copyOutboundDecoratorsToStackFailureAck(SipMessage& ack)
01756 {
01757   std::vector<MessageDecorator*>::iterator i;
01758   for (i = mOutboundDecorators.begin();
01759        i != mOutboundDecorators.end(); i++)
01760   {
01761      if((*i)->copyToStackFailureAcks())
01762      {
01763         ack.addOutboundDecorator(*(new auto_ptr<MessageDecorator>((*i)->clone())));
01764      }    
01765   }
01766 }
01767 
01768 /* ====================================================================
01769  * The Vovida Software License, Version 1.0 
01770  * 
01771  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
01772  * 
01773  * Redistribution and use in source and binary forms, with or without
01774  * modification, are permitted provided that the following conditions
01775  * are met:
01776  * 
01777  * 1. Redistributions of source code must retain the above copyright
01778  *    notice, this list of conditions and the following disclaimer.
01779  * 
01780  * 2. Redistributions in binary form must reproduce the above copyright
01781  *    notice, this list of conditions and the following disclaimer in
01782  *    the documentation and/or other materials provided with the
01783  *    distribution.
01784  * 
01785  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
01786  *    and "Vovida Open Communication Application Library (VOCAL)" must
01787  *    not be used to endorse or promote products derived from this
01788  *    software without prior written permission. For written
01789  *    permission, please contact vocal@vovida.org.
01790  *
01791  * 4. Products derived from this software may not be called "VOCAL", nor
01792  *    may "VOCAL" appear in their name, without prior written
01793  *    permission of Vovida Networks, Inc.
01794  * 
01795  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
01796  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
01797  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
01798  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
01799  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
01800  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
01801  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
01802  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
01803  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
01804  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
01805  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
01806  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
01807  * DAMAGE.
01808  * 
01809  * ====================================================================
01810  * 
01811  * This software consists of voluntary contributions made by Vovida
01812  * Networks, Inc. and many individuals on behalf of Vovida Networks,
01813  * Inc.  For more information on Vovida Networks, Inc., please see
01814  * <http://www.vovida.org/>.
01815  *
01816  * vi: set shiftwidth=3 expandtab:
01817  */