|
reSIProcate/stack
9694
|
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 */
1.7.5.1