Coverage Report

Created: 2026-01-09 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/resiprocate/resip/stack/SipMessage.cxx
Line
Count
Source
1
#if defined(HAVE_CONFIG_H)
2
#include "config.h"
3
#endif
4
5
#include "resip/stack/Contents.hxx"
6
#include "resip/stack/Embedded.hxx"
7
#include "resip/stack/OctetContents.hxx"
8
#include "resip/stack/HeaderFieldValueList.hxx"
9
#include "resip/stack/SipMessage.hxx"
10
#include "resip/stack/ExtensionHeader.hxx"
11
#include "rutil/Coders.hxx"
12
#include "rutil/CountStream.hxx"
13
#include "rutil/Logger.hxx"
14
#include "rutil/MD5Stream.hxx"
15
#include "rutil/compat.hxx"
16
#include "rutil/vmd5.hxx"
17
#include "rutil/Coders.hxx"
18
#include "rutil/Random.hxx"
19
#include "rutil/ParseBuffer.hxx"
20
#include "resip/stack/MsgHeaderScanner.hxx"
21
//#include "rutil/WinLeakCheck.hxx"  // not compatible with placement new used below
22
#include <utility>
23
24
using namespace resip;
25
using namespace std;
26
27
#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
28
29
/// Clears the container. Does not free `HeaderFieldValueList` objects but clears them and marks as "unused".
30
void
31
SipMessage::KnownHeaders::clear() noexcept
32
0
{
33
0
   for (iterator it = begin(), e = end(); it != e;)
34
0
   {
35
0
      erase(it++);
36
0
   }
37
0
}
38
39
/// Clears the container and invokes the dispose function on every element.
40
template<typename Disposer>
41
inline void
42
SipMessage::KnownHeaders::clearAndDispose(Disposer&& disposer) noexcept
43
18.4k
{
44
18.4k
   for (reference elem : mHeaders)
45
1.21k
   {
46
1.21k
      disposer(elem);
47
1.21k
   }
48
49
18.4k
   mHeaders.clear();
50
18.4k
   mSize = 0;
51
18.4k
   resetIndices();
52
18.4k
}
53
54
/// Erases an element. Does not free the `HeaderFieldValueList` object but clears it and marks as "unused".
55
void
56
SipMessage::KnownHeaders::erase(iterator it) noexcept
57
0
{
58
0
   resip_assert(it->getType() != Headers::UNKNOWN);
59
0
   resip_assert(it->getValues() != nullptr);
60
0
   resip_assert(mSize > 0);
61
62
0
   it->getValues()->clear();
63
0
   it->setType(Headers::UNKNOWN);
64
0
   --mSize;
65
0
}
66
67
/// Constructs or reuses a previously erased element for a given header type.
68
template<typename ValuesFactory>
69
inline SipMessage::KnownHeaders::iterator
70
SipMessage::KnownHeaders::insert(Headers::Type type, ValuesFactory&& valuesFactory)
71
665k
{
72
665k
   resip_assert(static_cast<size_type>(type) < (sizeof(mHeaderIndices) / sizeof(*mHeaderIndices)));
73
665k
   size_type pos = mHeaderIndices[type];
74
665k
   if (pos >= mHeaders.size())
75
1.21k
   {
76
1.21k
      pos = mHeaders.size();
77
1.21k
      mHeaders.emplace_back(type);
78
1.21k
      try
79
1.21k
      {
80
1.21k
         mHeaders[pos].setValues(valuesFactory());
81
1.21k
      }
82
1.21k
      catch (...)
83
1.21k
      {
84
0
         mHeaders.pop_back();
85
0
         throw;
86
0
      }
87
1.21k
      mHeaderIndices[type] = static_cast<HeaderIndex>(pos);
88
1.21k
      ++mSize;
89
1.21k
   }
90
663k
   else if (mHeaders[pos].getType() == Headers::UNKNOWN)
91
0
   {
92
      // Reuse the previously erased element
93
0
      mHeaders[pos].setType(type);
94
0
      ++mSize;
95
0
   }
96
97
665k
   return iterator(mHeaders.begin() + pos, mHeaders.end());
98
665k
}
Unexecuted instantiation: SipMessage.cxx:resip::SipMessage::KnownHeaders::UsedIterator<std::__1::__wrap_iter<resip::SipMessage::KnownHeaders::HeaderInfo*> > resip::SipMessage::KnownHeaders::insert<resip::SipMessage::init(resip::SipMessage const&)::$_0>(resip::Headers::Type, resip::SipMessage::init(resip::SipMessage const&)::$_0&&)
SipMessage.cxx:resip::SipMessage::KnownHeaders::UsedIterator<std::__1::__wrap_iter<resip::SipMessage::KnownHeaders::HeaderInfo*> > resip::SipMessage::KnownHeaders::insert<resip::SipMessage::ensureHeaders(resip::Headers::Type)::$_0>(resip::Headers::Type, resip::SipMessage::ensureHeaders(resip::Headers::Type)::$_0&&)
Line
Count
Source
71
665k
{
72
665k
   resip_assert(static_cast<size_type>(type) < (sizeof(mHeaderIndices) / sizeof(*mHeaderIndices)));
73
665k
   size_type pos = mHeaderIndices[type];
74
665k
   if (pos >= mHeaders.size())
75
1.21k
   {
76
1.21k
      pos = mHeaders.size();
77
1.21k
      mHeaders.emplace_back(type);
78
1.21k
      try
79
1.21k
      {
80
1.21k
         mHeaders[pos].setValues(valuesFactory());
81
1.21k
      }
82
1.21k
      catch (...)
83
1.21k
      {
84
0
         mHeaders.pop_back();
85
0
         throw;
86
0
      }
87
1.21k
      mHeaderIndices[type] = static_cast<HeaderIndex>(pos);
88
1.21k
      ++mSize;
89
1.21k
   }
90
663k
   else if (mHeaders[pos].getType() == Headers::UNKNOWN)
91
0
   {
92
      // Reuse the previously erased element
93
0
      mHeaders[pos].setType(type);
94
0
      ++mSize;
95
0
   }
96
97
665k
   return iterator(mHeaders.begin() + pos, mHeaders.end());
98
665k
}
Unexecuted instantiation: SipMessage.cxx:resip::SipMessage::KnownHeaders::UsedIterator<std::__1::__wrap_iter<resip::SipMessage::KnownHeaders::HeaderInfo*> > resip::SipMessage::KnownHeaders::insert<resip::SipMessage::setRawHeader(resip::HeaderFieldValueList const*, resip::Headers::Type)::$_0>(resip::Headers::Type, resip::SipMessage::setRawHeader(resip::HeaderFieldValueList const*, resip::Headers::Type)::$_0&&)
99
100
/// Resets all header indices to `InvalidHeaderIndex`
101
void
102
SipMessage::KnownHeaders::resetIndices() noexcept
103
27.6k
{
104
27.6k
   for (HeaderIndex& index : mHeaderIndices)
105
2.65M
      index = InvalidHeaderIndex;
106
27.6k
}
107
108
/// Finds header information, if present in the list. Returns `end()` if not found. Does not produce "unused" entries.
109
SipMessage::KnownHeaders::iterator
110
SipMessage::KnownHeaders::find(Headers::Type type) noexcept
111
18.2k
{
112
18.2k
   resip_assert(static_cast<size_type>(type) < (sizeof(mHeaderIndices) / sizeof(*mHeaderIndices)));
113
18.2k
   if (mHeaderIndices[type] < mHeaders.size())
114
13.4k
   {
115
13.4k
      TypedHeaders::iterator it = mHeaders.begin() + mHeaderIndices[type];
116
13.4k
      if (it->getType() != Headers::UNKNOWN)
117
13.4k
         return iterator(it, mHeaders.end());
118
13.4k
   }
119
120
4.83k
   return end();
121
18.2k
}
122
123
124
bool SipMessage::checkContentLength=true;
125
126
SipMessage::SipMessage(const Tuple *receivedTransportTuple)
127
9.23k
   : mIsDecorated(false),
128
9.23k
     mIsBadAck200(false),
129
9.23k
     mIsExternal(receivedTransportTuple != 0),  // may be modified later by setFromTU or setFromExternal
130
9.23k
     mKnownHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase>(&mPool)),
131
#ifndef __SUNPRO_CC
132
9.23k
     mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase>(&mPool)),
133
#else
134
     mUnknownHeaders(),
135
#endif
136
9.23k
     mRequest(false),
137
9.23k
     mResponse(false),
138
9.23k
     mInvalid(false),
139
9.23k
     mCreatedTime(Timer::getTimeMicroSec()),
140
9.23k
     mTlsDomain(Data::Empty)
141
9.23k
{
142
9.23k
   if(receivedTransportTuple)
143
0
   {
144
0
       mReceivedTransportTuple = *receivedTransportTuple;
145
0
   }
146
   // !bwc! TODO make this tunable
147
9.23k
   mKnownHeaders.reserve(16);
148
9.23k
   clear();
149
9.23k
}
150
151
SipMessage::SipMessage(const SipMessage& from)
152
0
   : mKnownHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase>(&mPool)),
153
#ifndef __SUNPRO_CC
154
0
     mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase>(&mPool)),
155
#else
156
     mUnknownHeaders(),
157
#endif
158
0
     mCreatedTime(Timer::getTimeMicroSec())
159
0
{
160
0
   init(from);
161
0
}
162
163
Message*
164
SipMessage::clone() const
165
0
{
166
0
   return new SipMessage(*this);
167
0
}
168
169
SipMessage& 
170
SipMessage::operator=(const SipMessage& rhs)
171
0
{
172
0
   if (this != &rhs)
173
0
   {
174
0
      freeMem();
175
0
      init(rhs);
176
0
   }
177
0
   return *this;
178
0
}
179
180
SipMessage::~SipMessage()
181
9.23k
{
182
//#define DINKYPOOL_PROFILING
183
#ifdef DINKYPOOL_PROFILING
184
   if (mPool.getHeapBytes() > 0)
185
   {
186
       InfoLog(<< "SipMessage mPool filled up and used " << mPool.getHeapBytes() << " bytes on the heap, consider increasing the mPool size (sizeof SipMessage is " << sizeof(SipMessage) << " bytes): msg="
187
           << std::endl << *this);
188
   }
189
   else
190
   {
191
       InfoLog(<< "SipMessage mPool used " << mPool.getPoolBytes() << " bytes of a total " << mPool.getPoolSizeBytes() << " bytes (sizeof SipMessage is " << sizeof(SipMessage) << " bytes): msg="
192
           << std::endl << *this);
193
   }
194
#endif
195
9.23k
   freeMem();
196
9.23k
}
197
198
void
199
SipMessage::clear(bool leaveResponseStuff)
200
9.23k
{
201
9.23k
   if(!leaveResponseStuff)
202
9.23k
   {
203
9.23k
      clearHeaders();
204
205
9.23k
      mBufferList.clear();
206
9.23k
   }
207
208
9.23k
   mUnknownHeaders.clear();
209
210
9.23k
   mStartLine = 0;
211
9.23k
   mContents = 0;
212
9.23k
   mContentsHfv.clear();
213
9.23k
   mForceTarget = 0;
214
9.23k
   mReason=0;
215
9.23k
   mOutboundDecorators.clear();
216
9.23k
}
217
218
void
219
SipMessage::init(const SipMessage& rhs)
220
0
{
221
0
   clear();
222
223
0
   mIsDecorated = rhs.mIsDecorated;
224
0
   mIsBadAck200 = rhs.mIsBadAck200;
225
0
   mIsExternal = rhs.mIsExternal;
226
0
   mReceivedTransportTuple = rhs.mReceivedTransportTuple;
227
0
   mSource = rhs.mSource;
228
0
   mDestination = rhs.mDestination;
229
0
   mRFC2543TransactionId = rhs.mRFC2543TransactionId;
230
0
   mRequest = rhs.mRequest;
231
0
   mResponse = rhs.mResponse;
232
0
   mInvalid = rhs.mInvalid;
233
0
   if(!rhs.mReason)
234
0
   {
235
0
      mReason=0;
236
0
   }
237
0
   else
238
0
   {
239
0
      mReason = new Data(*rhs.mReason);
240
0
   }
241
0
   mTlsDomain = rhs.mTlsDomain;
242
243
0
   mKnownHeaders.reserve(rhs.mKnownHeaders.size());
244
0
   for (KnownHeaders::const_reference info : rhs.mKnownHeaders)
245
0
   {
246
      // At this point the list must have no "unused" elements,
247
      // so the factory function will always be invoked
248
0
      mKnownHeaders.insert(info.getType(), [&] { return getCopyHfvl(*info.getValues()); });
249
0
   }
250
251
0
   for (UnknownHeaders::const_iterator i = rhs.mUnknownHeaders.begin();
252
0
        i != rhs.mUnknownHeaders.end(); i++)
253
0
   {
254
0
      mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(
255
0
                                   i->first,
256
0
                                   getCopyHfvl(*i->second)));
257
0
   }
258
0
   if (rhs.mStartLine != 0)
259
0
   {
260
0
      mStartLine = rhs.mStartLine->clone(mStartLineMem);
261
0
   }
262
0
   if (rhs.mContents != 0)
263
0
   {
264
0
      mContents = rhs.mContents->clone();
265
0
   }
266
0
   else if (rhs.mContentsHfv.getBuffer() != 0)
267
0
   {
268
0
      mContentsHfv.copyWithPadding(rhs.mContentsHfv);
269
0
   }
270
0
   else
271
0
   {
272
      // no body to copy
273
0
   }
274
0
   if (rhs.mForceTarget != 0)
275
0
   {
276
0
      mForceTarget = new Uri(*rhs.mForceTarget);
277
0
   }
278
279
0
   if (rhs.mSecurityAttributes.get())
280
0
   {
281
282
0
      if (!mSecurityAttributes.get())
283
0
      {
284
0
         SecurityAttributes* attr = new SecurityAttributes();
285
0
         mSecurityAttributes.reset(attr);
286
0
      }
287
288
0
      if (rhs.mSecurityAttributes->isEncrypted())
289
0
      {
290
0
         mSecurityAttributes->setEncrypted();
291
0
      }
292
0
      mSecurityAttributes->setSignatureStatus(rhs.mSecurityAttributes->getSignatureStatus());
293
0
      mSecurityAttributes->setIdentity(rhs.mSecurityAttributes->getIdentity());
294
0
      mSecurityAttributes->setIdentityStrength(rhs.mSecurityAttributes->getIdentityStrength());
295
0
      mSecurityAttributes->setSigner(rhs.mSecurityAttributes->getSigner());
296
0
      mSecurityAttributes->setOutgoingEncryptionLevel(rhs.mSecurityAttributes->getOutgoingEncryptionLevel());
297
0
      mSecurityAttributes->setEncryptionPerformed(rhs.mSecurityAttributes->encryptionPerformed());
298
0
   }
299
0
   else
300
0
   {
301
0
      if (mSecurityAttributes.get())
302
0
      {
303
0
         mSecurityAttributes.reset();
304
0
      }
305
0
   }
306
307
0
   for(std::vector<MessageDecorator*>::const_iterator i=rhs.mOutboundDecorators.begin(); i!=rhs.mOutboundDecorators.end();++i)
308
0
   {
309
0
      mOutboundDecorators.push_back((*i)->clone());
310
0
   }
311
0
}
312
313
void
314
SipMessage::freeMem(bool leaveResponseStuff)
315
9.23k
{
316
9.23k
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
317
21.2k
        i != mUnknownHeaders.end(); i++)
318
12.0k
   {
319
12.0k
      freeHfvl(i->second);
320
12.0k
   }
321
322
9.23k
   if(!leaveResponseStuff)
323
9.23k
   {
324
9.23k
      clearHeaders();
325
326
9.23k
      for (vector<char*>::iterator i = mBufferList.begin();
327
900k
           i != mBufferList.end(); i++)
328
890k
      {
329
890k
         delete [] *i;
330
890k
      }
331
9.23k
   }
332
333
9.23k
   if(mStartLine)
334
575
   {
335
575
      mStartLine->~StartLine();
336
575
      mStartLine=0;
337
575
   }
338
339
9.23k
   delete mContents;
340
9.23k
   delete mForceTarget;
341
9.23k
   delete mReason;
342
343
9.23k
   for(std::vector<MessageDecorator*>::iterator i=mOutboundDecorators.begin();
344
9.23k
         i!=mOutboundDecorators.end();++i)
345
0
   {
346
0
      delete *i;
347
0
   }
348
9.23k
}
349
350
void
351
SipMessage::clearHeaders()
352
18.4k
{
353
18.4k
   mKnownHeaders.clearAndDispose([this](KnownHeaders::reference elem) noexcept { freeHfvl(elem.getValues()); });
354
18.4k
}
355
356
SipMessage*
357
SipMessage::make(const Data& data, bool isExternal)
358
6.11k
{
359
6.11k
   Tuple fakeWireTuple;
360
6.11k
   fakeWireTuple.setType(UDP);
361
6.11k
   SipMessage* msg = new SipMessage(isExternal ? &fakeWireTuple : 0);
362
363
6.11k
   size_t len = data.size();
364
6.11k
   char *buffer = new char[len + 5];
365
366
6.11k
   msg->addBuffer(buffer);
367
6.11k
   memcpy(buffer,data.data(), len);
368
6.11k
   MsgHeaderScanner msgHeaderScanner;
369
6.11k
   msgHeaderScanner.prepareForMessage(msg);
370
   
371
6.11k
   char *unprocessedCharPtr;
372
6.11k
   if (msgHeaderScanner.scanChunk(buffer, (unsigned int)len, &unprocessedCharPtr) != MsgHeaderScanner::scrEnd)
373
5.95k
   {
374
5.95k
      DebugLog(<<"Scanner rejecting buffer as unparsable / fragmented.");
375
5.95k
      DebugLog(<< data);
376
5.95k
      delete msg; 
377
5.95k
      msg = 0; 
378
5.95k
      return 0;
379
5.95k
   }
380
381
   // no pp error
382
153
   unsigned int used = (unsigned int)(unprocessedCharPtr - buffer);
383
384
153
   if (used < len)
385
151
   {
386
      // body is present .. add it up.
387
      // NB. The Sip Message uses an overlay (again)
388
      // for the body. It ALSO expects that the body
389
      // will be contiguous (of course).
390
      // it doesn't need a new buffer in UDP b/c there
391
      // will only be one datagram per buffer. (1:1 strict)
392
393
151
      msg->setBody(buffer+used,uint32_t(len-used));
394
      //DebugLog(<<"added " << len-used << " byte body");
395
151
   }
396
397
153
   return msg;
398
6.11k
}
399
400
void
401
SipMessage::parseAllHeaders()
402
0
{
403
0
   for (KnownHeaders::reference info : mKnownHeaders)
404
0
   {
405
0
      HeaderFieldValueList* hfvl = info.getValues();
406
0
      resip_assert(hfvl != nullptr);
407
0
      if (!Headers::isMulti(info.getType()) && hfvl->parsedEmpty())
408
0
      {
409
0
         hfvl->push_back(nullptr, 0, false);
410
0
      }
411
412
0
      ParserContainerBase* pc = hfvl->getParserContainer();
413
0
      if (!pc)
414
0
      {
415
0
         pc = HeaderBase::getInstance(info.getType())->makeContainer(hfvl);
416
0
         hfvl->setParserContainer(pc);
417
0
      }
418
419
0
      pc->parseAll();
420
0
   }
421
422
0
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
423
0
        i != mUnknownHeaders.end(); i++)
424
0
   {
425
0
      ParserContainerBase* scs = i->second->getParserContainer();
426
0
      if (!scs)
427
0
      {
428
0
         scs=makeParserContainer<StringCategory>(i->second,Headers::RESIP_DO_NOT_USE);
429
0
         i->second->setParserContainer(scs);
430
0
      }
431
      
432
0
      scs->parseAll();
433
0
   }
434
   
435
0
   resip_assert(mStartLine);
436
437
0
   mStartLine->checkParsed();
438
   
439
0
   getContents();
440
0
}
441
442
const Data& 
443
SipMessage::getTransactionId() const
444
0
{
445
0
   if (empty(h_Vias))
446
0
   {
447
0
      InfoLog (<< "Bad message with no Vias: " << *this);
448
0
      throw Exception("No Via in message", __FILE__,__LINE__);
449
0
   }
450
   
451
0
   resip_assert(exists(h_Vias) && !header(h_Vias).empty());
452
0
   if( exists(h_Vias) && header(h_Vias).front().exists(p_branch) 
453
0
       && header(h_Vias).front().param(p_branch).hasMagicCookie() 
454
0
       && (!header(h_Vias).front().param(p_branch).getTransactionId().empty())
455
0
     )
456
0
   {
457
0
      return header(h_Vias).front().param(p_branch).getTransactionId();
458
0
   }
459
0
   else
460
0
   {
461
0
      if (mRFC2543TransactionId.empty())
462
0
      {
463
0
         compute2543TransactionHash();
464
0
      }
465
0
      return mRFC2543TransactionId;
466
0
   }
467
0
}
468
469
void
470
SipMessage::compute2543TransactionHash() const
471
0
{
472
0
   resip_assert (mRFC2543TransactionId.empty());
473
   
474
   /*  From rfc3261, 17.2.3
475
       The INVITE request matches a transaction if the Request-URI, To tag,
476
       From tag, Call-ID, CSeq, and top Via header field match those of the
477
       INVITE request which created the transaction.  In this case, the
478
       INVITE is a retransmission of the original one that created the
479
       transaction.  
480
481
       The ACK request matches a transaction if the Request-URI, From tag,
482
       Call-ID, CSeq number (not the method), and top Via header field match
483
       those of the INVITE request which created the transaction, and the To
484
       tag of the ACK matches the To tag of the response sent by the server
485
       transaction.  
486
487
       Matching is done based on the matching rules defined for each of those
488
       header fields.  Inclusion of the tag in the To header field in the ACK
489
       matching process helps disambiguate ACK for 2xx from ACK for other
490
       responses at a proxy, which may have forwarded both responses (This
491
       can occur in unusual conditions.  Specifically, when a proxy forked a
492
       request, and then crashes, the responses may be delivered to another
493
       proxy, which might end up forwarding multiple responses upstream).  An
494
       ACK request that matches an INVITE transaction matched by a previous
495
       ACK is considered a retransmission of that previous ACK.
496
497
       For all other request methods, a request is matched to a transaction
498
       if the Request-URI, To tag, From tag, Call-ID, CSeq (including the
499
       method), and top Via header field match those of the request that
500
       created the transaction.  Matching is done based on the matching
501
   */
502
503
   // If it is here and isn't a request, leave the transactionId empty, this
504
   // will cause the Transaction to send it statelessly
505
506
0
   if (isRequest())
507
0
   {
508
0
      MD5Stream strm;
509
      // See section 17.2.3 Matching Requests to Server Transactions in rfc 3261
510
511
//#define VONAGE_FIX
512
0
#ifndef VONAGE_FIX         
513
0
      strm << header(h_RequestLine).uri().scheme();
514
0
      strm << header(h_RequestLine).uri().user();
515
0
      strm << header(h_RequestLine).uri().host();
516
0
      strm << header(h_RequestLine).uri().port();
517
0
      strm << header(h_RequestLine).uri().password();
518
0
      strm << header(h_RequestLine).uri().commutativeParameterHash();
519
0
#endif
520
0
      if (!empty(h_Vias))
521
0
      {
522
0
         strm << header(h_Vias).front().protocolName();
523
0
         strm << header(h_Vias).front().protocolVersion();
524
0
         strm << header(h_Vias).front().transport();
525
0
         strm << header(h_Vias).front().sentHost();
526
0
         strm << header(h_Vias).front().sentPort();
527
0
         strm << header(h_Vias).front().commutativeParameterHash();
528
0
      }
529
         
530
0
      if (header(h_From).exists(p_tag))
531
0
      {
532
0
         strm << header(h_From).param(p_tag);
533
0
      }
534
535
      // Only include the totag for non-invite requests
536
0
      if (header(h_RequestLine).getMethod() != INVITE && 
537
0
          header(h_RequestLine).getMethod() != ACK && 
538
0
          header(h_RequestLine).getMethod() != CANCEL &&
539
0
          header(h_To).exists(p_tag))
540
0
      {
541
0
         strm << header(h_To).param(p_tag);
542
0
      }
543
544
0
      strm << header(h_CallID).value();
545
546
0
      if (header(h_RequestLine).getMethod() == ACK || 
547
0
          header(h_RequestLine).getMethod() == CANCEL)
548
0
      {
549
0
         strm << INVITE;
550
0
         strm << header(h_CSeq).sequence();
551
0
      }
552
0
      else
553
0
      {
554
0
         strm << header(h_CSeq).method();
555
0
         strm << header(h_CSeq).sequence();
556
0
      }
557
           
558
0
      mRFC2543TransactionId = strm.getHex();
559
0
   }
560
0
   else
561
0
   {
562
0
      InfoLog (<< "Trying to compute a transaction id on a 2543 response. Drop the response");
563
0
      DebugLog (<< *this);
564
0
      throw Exception("Drop invalid 2543 response", __FILE__, __LINE__);
565
0
   }
566
0
}
567
568
const Data&
569
SipMessage::getRFC2543TransactionId() const
570
0
{
571
0
   if(empty(h_Vias) ||
572
0
      !header(h_Vias).front().exists(p_branch) ||
573
0
      !header(h_Vias).front().param(p_branch).hasMagicCookie() ||
574
0
      header(h_Vias).front().param(p_branch).getTransactionId().empty())
575
0
   {
576
0
      if (mRFC2543TransactionId.empty())
577
0
      {
578
0
         compute2543TransactionHash();
579
0
      }
580
0
   }
581
0
   return mRFC2543TransactionId;
582
0
}
583
584
585
Data
586
SipMessage::getCanonicalIdentityString() const
587
0
{
588
0
   Data result;
589
0
   DataStream strm(result);
590
   
591
   // digest-string = addr-spec ":" addr-spec ":" callid ":" 1*DIGIT SP method ":"
592
   //             SIP-Date ":" [ addr-spec ] ":" message-body
593
  
594
0
   strm << header(h_From).uri();
595
0
   strm << Symbols::BAR;
596
   
597
0
   strm << header(h_To).uri();
598
0
   strm << Symbols::BAR;
599
   
600
0
   strm << header(h_CallId).value();
601
0
   strm << Symbols::BAR;
602
   
603
0
   header(h_CSeq).sequence(); // force parsed
604
0
   header(h_CSeq).encodeParsed( strm );
605
0
   strm << Symbols::BAR;
606
   
607
   // if there is no date, it will throw 
608
0
   if ( empty(h_Date) )
609
0
   {
610
0
      WarningLog( << "Computing Identity on message with no Date header" );
611
      // TODO FIX - should it have a throw here ???? Help ???
612
0
   }
613
0
   header(h_Date).dayOfMonth(); // force it to be parsed 
614
0
   header(h_Date).encodeParsed( strm );
615
0
   strm << Symbols::BAR;
616
   
617
0
   if ( !empty(h_Contacts) )
618
0
   { 
619
0
      if ( header(h_Contacts).front().isAllContacts() )
620
0
      {
621
0
         strm << Symbols::STAR;
622
0
      }
623
0
      else
624
0
      {
625
0
         strm << header(h_Contacts).front().uri();
626
0
      }
627
0
   }
628
0
   strm << Symbols::BAR;
629
   
630
   // bodies 
631
0
   if (mContents != 0)
632
0
   {
633
0
      mContents->encode(strm);
634
0
   }
635
0
   else if (mContentsHfv.getBuffer() != 0)
636
0
   {
637
0
      mContentsHfv.encode(strm);
638
0
   }
639
640
0
   strm.flush();
641
642
0
   DebugLog( << "Indentity Canonical String is: " << result );
643
   
644
0
   return result;
645
0
}
646
647
648
void
649
SipMessage::setRFC2543TransactionId(const Data& tid)
650
0
{
651
0
   mRFC2543TransactionId = tid;
652
0
}
653
654
resip::MethodTypes
655
SipMessage::method() const
656
0
{
657
0
   resip::MethodTypes res=UNKNOWN;
658
0
   try
659
0
   {
660
0
      if(isRequest())
661
0
      {
662
0
         res=header(h_RequestLine).getMethod();
663
0
      }
664
0
      else if(isResponse())
665
0
      {
666
0
         res=header(h_CSeq).method();
667
0
      }
668
0
      else
669
0
      {
670
0
         resip_assert(0);
671
0
      }
672
0
   }
673
0
   catch(resip::ParseException&)
674
0
   {
675
0
   }
676
   
677
0
   return res;
678
0
}
679
680
const Data&
681
SipMessage::methodStr() const
682
0
{
683
0
   if(method()!=UNKNOWN)
684
0
   {
685
0
      return getMethodName(method());
686
0
   }
687
0
   else
688
0
   {
689
0
      try
690
0
      {
691
0
         if(isRequest())
692
0
         {
693
0
            return header(h_RequestLine).unknownMethodName();
694
0
         }
695
0
         else if(isResponse())
696
0
         {
697
0
            return header(h_CSeq).unknownMethodName();
698
0
         }
699
0
         else
700
0
         {
701
0
            resip_assert(0);
702
0
         }
703
0
      }
704
0
      catch(resip::ParseException&)
705
0
      {
706
0
      }
707
0
   }
708
0
   return Data::Empty;
709
0
}
710
711
static const Data requestEB("SipReq:  ");
712
static const Data responseEB("SipResp: ");
713
static const Data tidEB(" tid=");
714
static const Data contactEB(" contact=");
715
static const Data cseqEB(" cseq=");
716
static const Data slashEB(" / ");
717
static const Data wireEB(" from(wire)");
718
static const Data ftuEB(" from(tu)");
719
static const Data tlsdEB(" tlsd=");
720
EncodeStream&
721
SipMessage::encodeBrief(EncodeStream& str) const
722
0
{
723
0
   if (isRequest()) 
724
0
   {
725
0
      str << requestEB;
726
0
      MethodTypes meth = header(h_RequestLine).getMethod();
727
0
      if (meth != UNKNOWN)
728
0
      {
729
0
         str << getMethodName(meth);
730
0
      }
731
0
      else
732
0
      {
733
0
         str << header(h_RequestLine).unknownMethodName();
734
0
      }
735
      
736
0
      str << Symbols::SPACE;
737
0
      str << header(h_RequestLine).uri().getAor();
738
0
   }
739
0
   else if (isResponse())
740
0
   {
741
0
      str << responseEB;
742
0
      str << header(h_StatusLine).responseCode();
743
0
   }
744
0
   if (!empty(h_Vias))
745
0
   {
746
0
      str << tidEB;
747
0
      try
748
0
      {
749
0
         str << getTransactionId();
750
0
      }
751
0
      catch(BaseException&)  // Could be SipMessage::Exception or ParseException
752
0
      {
753
0
         str << "BAD-VIA";
754
0
      }
755
0
   }
756
0
   else
757
0
   {
758
0
      str << " NO-VIAS ";
759
0
   }
760
761
0
   str << cseqEB;
762
0
   str << header(h_CSeq);
763
764
0
   try
765
0
   {
766
0
      if (!empty(h_Contacts))
767
0
      {
768
0
         str << contactEB;
769
0
         str << header(h_Contacts).front().uri().getAor();
770
0
      }
771
0
   }
772
0
   catch(resip::ParseException&)
773
0
   {
774
0
      str << " MALFORMED CONTACT ";
775
0
   }
776
   
777
0
   str << slashEB;
778
0
   str << header(h_CSeq).sequence();
779
0
   str << (mIsExternal ? wireEB : ftuEB);
780
0
   if (!mTlsDomain.empty())
781
0
   {
782
0
      str << tlsdEB << mTlsDomain;
783
0
   }
784
   
785
0
   return str;
786
0
}
787
788
bool
789
SipMessage::isClientTransaction() const
790
0
{
791
0
   resip_assert(mRequest || mResponse);
792
0
   return ((mIsExternal && mResponse) || (!mIsExternal && mRequest));
793
0
}
794
795
EncodeStream&
796
SipMessage::encode(EncodeStream& str) const
797
0
{
798
0
   return encode(str, false);
799
0
}
800
801
EncodeStream&
802
SipMessage::encodeSipFrag(EncodeStream& str) const
803
0
{
804
0
   return encode(str, true);
805
0
}
806
807
// dynamic_cast &str to DataStream* to avoid CountStream?
808
809
EncodeStream&
810
SipMessage::encode(EncodeStream& str, bool isSipFrag) const
811
0
{
812
0
   if (mStartLine != 0)
813
0
   {
814
0
      mStartLine->encode(str);
815
0
      str << "\r\n";
816
0
   }
817
818
0
   Data contents;
819
0
   if (mContents != 0)
820
0
   {
821
0
      oDataStream temp(contents);
822
0
      mContents->encode(temp);
823
0
   }
824
0
   else if (mContentsHfv.getBuffer() != 0)
825
0
   {
826
#if 0
827
      // !bwc! This causes an additional copy; sure would be nice to have a way
828
      // to get a data to take on a buffer with Data::Share _after_ construction
829
      contents.append(mContentsHfv.getBuffer(), mContentsHfv.getLength());
830
#else
831
      // .kw. Your wish is granted
832
0
      mContentsHfv.toShareData(contents);
833
0
#endif
834
0
   }
835
836
0
   for (KnownHeaders::const_reference info : mKnownHeaders)
837
0
   {
838
0
      if (info.getType() != Headers::ContentLength) // !dlb! hack...
839
0
      {
840
0
         info.getValues()->encode(info.getType(), str);
841
0
      }
842
0
   }
843
844
0
   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); 
845
0
        i != mUnknownHeaders.end(); i++)
846
0
   {
847
0
      i->second->encode(i->first, str);
848
0
   }
849
850
0
   if(!isSipFrag || !contents.empty())
851
0
   {
852
0
      str << "Content-Length: " << contents.size() << "\r\n";
853
0
   }
854
855
0
   str << Symbols::CRLF;
856
   
857
0
   str << contents;
858
0
   return str;
859
0
}
860
861
EncodeStream&
862
SipMessage::encodeSingleHeader(Headers::Type type, EncodeStream& str) const
863
0
{
864
0
   auto it = mKnownHeaders.find(type);
865
0
   if (it != mKnownHeaders.end())
866
0
   {
867
0
      it->getValues()->encode(type, str);
868
0
   }
869
0
   return str;
870
0
}
871
872
EncodeStream& 
873
SipMessage::encodeEmbedded(EncodeStream& str) const
874
0
{
875
0
   bool first = true;
876
0
   for (KnownHeaders::const_reference info : mKnownHeaders)
877
0
   {
878
0
      if (info.getType() != Headers::ContentLength)
879
0
      {
880
0
         if (first)
881
0
         {
882
0
            str << Symbols::QUESTION;
883
0
            first = false;
884
0
         }
885
0
         else
886
0
         {
887
0
            str << Symbols::AMPERSAND;
888
0
         }
889
0
         info.getValues()->encodeEmbedded(Headers::getHeaderName(info.getType()), str);
890
0
      }
891
0
   }
892
893
0
   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); 
894
0
        i != mUnknownHeaders.end(); i++)
895
0
   {
896
0
      if (first)
897
0
      {
898
0
         str << Symbols::QUESTION;
899
0
         first = false;
900
0
      }
901
0
      else
902
0
      {
903
0
         str << Symbols::AMPERSAND;
904
0
      }
905
0
      i->second->encodeEmbedded(i->first, str);
906
0
   }
907
908
0
   if (mContents != 0 || mContentsHfv.getBuffer() != 0)
909
0
   {
910
0
      if (first)
911
0
      {
912
0
         str << Symbols::QUESTION;
913
0
      }
914
0
      else
915
0
      {
916
0
         str << Symbols::AMPERSAND;
917
0
      }
918
0
      str << "body=";
919
0
      Data contents;
920
      // !dlb! encode escaped for characters
921
      // .kw. what does that mean? what needs to be escaped?
922
0
      if(mContents != 0)
923
0
      {
924
0
         DataStream s(contents);
925
0
         mContents->encode(s);
926
0
      }
927
0
      else
928
0
      {
929
         // .kw. Early code did:
930
         // DataStream s(contents);
931
         // mContentsHfv->encode(str);
932
         // str << Embedded::encode(contents);
933
         // .kw. which I think is buggy b/c Hfv was written directly
934
         // to str and skipped the encode step via contents
935
0
         mContentsHfv.toShareData(contents);
936
0
      }
937
0
      str << Embedded::encode(contents);
938
0
   }
939
0
   return str;
940
0
}
941
942
void
943
SipMessage::addBuffer(char* buf)
944
890k
{
945
890k
   mBufferList.push_back(buf);
946
890k
}
947
948
void 
949
SipMessage::setStartLine(const char* st, int len)
950
575
{
951
575
   if(len >= 4 && !strncasecmp(st,"SIP/",4))
952
4
   {
953
      // Response
954
4
      mStartLine = new (mStartLineMem) StatusLine(st, len);
955
      //!dcm! should invoke the statusline parser here once it does limited validation
956
4
      mResponse = true;
957
4
   }
958
571
   else
959
571
   {
960
      // Request
961
571
      mStartLine = new (mStartLineMem) RequestLine(st, len);
962
      //!dcm! should invoke the responseline parser here once it does limited validation
963
571
      mRequest = true;
964
571
   }
965
966
967
// .bwc. This stuff is so needlessly complicated. Much, much simpler, faster,
968
// and more robust code above.
969
//   ParseBuffer pb(st, len);
970
//   const char* start;
971
//   start = pb.skipWhitespace();
972
//   pb.skipNonWhitespace();
973
//   MethodTypes method = getMethodType(start, pb.position() - start);
974
//   if (method == UNKNOWN) //probably a status line
975
//   {
976
//      start = pb.skipChar(Symbols::SPACE[0]);
977
//      pb.skipNonWhitespace();
978
//      if ((pb.position() - start) == 3)
979
//      {
980
//         mStartLine = new (mStartLineMem) StatusLine(st, len ,Headers::NONE);
981
//         //!dcm! should invoke the statusline parser here once it does limited validation
982
//         mResponse = true;
983
//      }
984
//   }
985
//   if (!mResponse)
986
//   {
987
//      mStartLine = new (mStartLineMem) RequestLine(st, len, Headers::NONE);
988
//      //!dcm! should invoke the responseline parser here once it does limited validation
989
//      mRequest = true;
990
//   }
991
575
}
992
993
void 
994
SipMessage::setBody(const char* start, uint32_t len)
995
9.30k
{
996
9.30k
   if(checkContentLength)
997
9.30k
   {
998
9.30k
      if(exists(h_ContentLength))
999
4.47k
      {
1000
4.47k
         try
1001
4.47k
         {
1002
4.47k
            const_header(h_ContentLength).checkParsed();
1003
4.47k
         }
1004
4.47k
         catch(resip::ParseException& e)
1005
4.47k
         {
1006
112
            if(!mReason)
1007
112
            {
1008
112
               mReason=new Data;
1009
112
            }
1010
            
1011
112
            if(mInvalid)
1012
0
            {
1013
0
               mReason->append(",",1);
1014
0
            }
1015
1016
112
            mInvalid=true; 
1017
112
            mReason->append("Malformed Content-Length",24);
1018
112
            InfoLog(<< "Malformed Content-Length. Ignoring. " << e);
1019
112
            header(h_ContentLength).value()=len;
1020
112
         }
1021
         
1022
4.47k
         uint32_t contentLength=const_header(h_ContentLength).value();
1023
         
1024
4.47k
         if(len > contentLength)
1025
2.43k
         {
1026
2.43k
            InfoLog(<< (len-contentLength) << " extra bytes after body. Ignoring these bytes.");
1027
2.43k
         }
1028
2.04k
         else if(len < contentLength)
1029
119
         {
1030
119
            InfoLog(<< "Content Length (" << contentLength << ") is "
1031
119
                    << (contentLength-len) << " bytes larger than body (" << len << ")!"
1032
119
                    << " (We are supposed to 400 this) ");
1033
1034
119
            if(!mReason)
1035
85
            {
1036
85
               mReason=new Data;
1037
85
            }
1038
1039
119
            if(mInvalid)
1040
34
            {
1041
34
               mReason->append(",",1);
1042
34
            }
1043
1044
119
            mInvalid=true; 
1045
119
            mReason->append("Bad Content-Length (larger than datagram)",41);
1046
119
            header(h_ContentLength).value()=len;
1047
119
            contentLength=len;
1048
                     
1049
119
         }
1050
         
1051
4.47k
         mContentsHfv.init(start,contentLength, false);
1052
4.47k
      }
1053
4.83k
      else
1054
4.83k
      {
1055
4.83k
         InfoLog(<< "Message has a body, but no Content-Length header.");
1056
4.83k
         mContentsHfv.init(start,len, false);
1057
4.83k
      }
1058
9.30k
   }
1059
0
   else
1060
0
   {
1061
0
      mContentsHfv.init(start,len, false);
1062
0
   }
1063
9.30k
}
1064
1065
void
1066
SipMessage::setRawBody(const HeaderFieldValue& body)
1067
0
{
1068
0
   setContents(0);
1069
0
   mContentsHfv = body;
1070
0
}
1071
1072
1073
void
1074
SipMessage::setContents(unique_ptr<Contents> contents)
1075
0
{
1076
0
   Contents* contentsP = contents.release();
1077
1078
0
   delete mContents;
1079
0
   mContents = 0;
1080
0
   mContentsHfv.clear();
1081
1082
0
   if (contentsP == 0)
1083
0
   {
1084
      // The semantics of setContents(0) are to delete message contents
1085
0
      remove(h_ContentType);
1086
0
      remove(h_ContentDisposition);
1087
0
      remove(h_ContentTransferEncoding);
1088
0
      remove(h_ContentLanguages);
1089
0
      return;
1090
0
   }
1091
1092
0
   mContents = contentsP;
1093
1094
   // copy contents headers into message
1095
0
   if (mContents->exists(h_ContentDisposition))
1096
0
   {
1097
0
      header(h_ContentDisposition) = mContents->header(h_ContentDisposition);
1098
0
   }
1099
0
   if (mContents->exists(h_ContentTransferEncoding))
1100
0
   {
1101
0
      header(h_ContentTransferEncoding) = mContents->header(h_ContentTransferEncoding);
1102
0
   }
1103
0
   if (mContents->exists(h_ContentLanguages))
1104
0
   {
1105
0
      header(h_ContentLanguages) = mContents->header(h_ContentLanguages);
1106
0
   }
1107
0
   if (mContents->exists(h_ContentType))
1108
0
   {
1109
0
      header(h_ContentType) = mContents->header(h_ContentType);
1110
0
      resip_assert( header(h_ContentType).type() == mContents->getType().type() );
1111
0
      resip_assert( header(h_ContentType).subType() == mContents->getType().subType() );
1112
0
   }
1113
0
   else
1114
0
   {
1115
0
      header(h_ContentType) = mContents->getType();
1116
0
   }
1117
0
}
1118
1119
void 
1120
SipMessage::setContents(const Contents* contents)
1121
0
{ 
1122
0
   if (contents)
1123
0
   {
1124
0
      setContents(unique_ptr<Contents>(contents->clone()));
1125
0
   }
1126
0
   else
1127
0
   {
1128
0
      setContents(unique_ptr<Contents>());
1129
0
   }
1130
0
}
1131
1132
Contents*
1133
SipMessage::getContents() const
1134
0
{
1135
0
   if (mContents == 0 && mContentsHfv.getBuffer() != 0)
1136
0
   {
1137
0
      if (empty(h_ContentType) ||
1138
0
            !const_header(h_ContentType).isWellFormed())
1139
0
      {
1140
0
         StackLog(<< "SipMessage::getContents: ContentType header does not exist - implies no contents");
1141
0
         return 0;
1142
0
      }
1143
0
      DebugLog(<< "SipMessage::getContents: " 
1144
0
               << const_header(h_ContentType).type()
1145
0
               << "/"
1146
0
               << const_header(h_ContentType).subType());
1147
1148
0
      if ( ContentsFactoryBase::getFactoryMap().find(const_header(h_ContentType)) == ContentsFactoryBase::getFactoryMap().end() )
1149
0
      {
1150
0
         InfoLog(<< "SipMessage::getContents: got content type ("
1151
0
                 << const_header(h_ContentType).type()
1152
0
                 << "/"
1153
0
                 << const_header(h_ContentType).subType()
1154
0
                 << ") that is not known, "
1155
0
                 << "returning as opaque application/octet-stream");
1156
0
         mContents = ContentsFactoryBase::getFactoryMap()[OctetContents::getStaticType()]->create(mContentsHfv, OctetContents::getStaticType());
1157
0
      }
1158
0
      else
1159
0
      {
1160
0
         mContents = ContentsFactoryBase::getFactoryMap()[const_header(h_ContentType)]->create(mContentsHfv, const_header(h_ContentType));
1161
0
      }
1162
0
      resip_assert( mContents );
1163
      
1164
      // copy contents headers into the contents
1165
0
      if (!empty(h_ContentDisposition))
1166
0
      {
1167
0
         mContents->header(h_ContentDisposition) = const_header(h_ContentDisposition);
1168
0
      }
1169
0
      if (!empty(h_ContentTransferEncoding))
1170
0
      {
1171
0
         mContents->header(h_ContentTransferEncoding) = const_header(h_ContentTransferEncoding);
1172
0
      }
1173
0
      if (!empty(h_ContentLanguages))
1174
0
      {
1175
0
         mContents->header(h_ContentLanguages) = const_header(h_ContentLanguages);
1176
0
      }
1177
0
      if (!empty(h_ContentType))
1178
0
      {
1179
0
         mContents->header(h_ContentType) = const_header(h_ContentType);
1180
0
      }
1181
      // !dlb! Content-Transfer-Encoding?
1182
0
   }
1183
0
   return mContents;
1184
0
}
1185
1186
unique_ptr<Contents>
1187
SipMessage::releaseContents()
1188
0
{
1189
0
   Contents* c=getContents();
1190
   // .bwc. unique_ptr owns the Contents. No other references allowed!
1191
0
   unique_ptr<Contents> ret(c ? c->clone() : nullptr);
1192
0
   setContents(nullptr);
1193
1194
0
   if (ret != nullptr && !ret->isWellFormed())
1195
0
   {
1196
0
      ret.reset();
1197
0
   }
1198
1199
0
   return ret;
1200
0
}
1201
1202
// unknown header interface
1203
const StringCategories& 
1204
SipMessage::header(const ExtensionHeader& headerName) const
1205
0
{
1206
0
   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin();
1207
0
        i != mUnknownHeaders.end(); i++)
1208
0
   {      
1209
0
      if (isEqualNoCase(i->first, headerName.getName()))
1210
0
      {
1211
0
         HeaderFieldValueList* hfvs = i->second;
1212
0
         if (hfvs->getParserContainer() == 0)
1213
0
         {
1214
0
            SipMessage* nc_this(const_cast<SipMessage*>(this));
1215
0
            hfvs->setParserContainer(nc_this->makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
1216
0
         }
1217
0
         return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
1218
0
      }
1219
0
   }
1220
   // missing extension header
1221
0
   resip_assert(false);
1222
1223
0
   return *(StringCategories*)0;
1224
0
}
1225
1226
StringCategories& 
1227
SipMessage::header(const ExtensionHeader& headerName)
1228
0
{
1229
0
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
1230
0
        i != mUnknownHeaders.end(); i++)
1231
0
   {
1232
0
      if (isEqualNoCase(i->first, headerName.getName()))
1233
0
      {
1234
0
         HeaderFieldValueList* hfvs = i->second;
1235
0
         if (hfvs->getParserContainer() == 0)
1236
0
         {
1237
0
            hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
1238
0
         }
1239
0
         return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
1240
0
      }
1241
0
   }
1242
1243
   // create the list empty
1244
0
   HeaderFieldValueList* hfvs = getEmptyHfvl();
1245
0
   hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
1246
0
   mUnknownHeaders.push_back(make_pair(headerName.getName(), hfvs));
1247
0
   return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
1248
0
}
1249
1250
bool
1251
SipMessage::exists(const ExtensionHeader& symbol) const
1252
0
{
1253
0
   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin();
1254
0
        i != mUnknownHeaders.end(); i++)
1255
0
   {
1256
0
      if (isEqualNoCase(i->first, symbol.getName()))
1257
0
      {
1258
0
         return true;
1259
0
      }
1260
0
   }
1261
0
   return false;
1262
0
}
1263
1264
void
1265
SipMessage::remove(const ExtensionHeader& headerName)
1266
0
{
1267
0
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
1268
0
        i != mUnknownHeaders.end(); i++)
1269
0
   {
1270
0
      if (isEqualNoCase(i->first, headerName.getName()))
1271
0
      {
1272
0
         freeHfvl(i->second);
1273
0
         mUnknownHeaders.erase(i);
1274
0
         return;
1275
0
      }
1276
0
   }
1277
0
}
1278
1279
void
1280
SipMessage::addHeader(Headers::Type header, const char* headerName, int headerLen, 
1281
                      const char* start, int len)
1282
1.44M
{
1283
1.44M
   if (header != Headers::UNKNOWN)
1284
664k
   {
1285
664k
      resip_assert(header > Headers::UNKNOWN && header < Headers::MAX_HEADERS);
1286
664k
      HeaderFieldValueList* hfvl = ensureHeaders(header);
1287
1288
664k
      if(Headers::isMulti(header))
1289
594k
      {
1290
594k
         if (len)
1291
570k
         {
1292
570k
            hfvl->push_back(start, len, false);
1293
570k
         }
1294
594k
      }
1295
70.3k
      else
1296
70.3k
      {
1297
#ifdef PEDANTIC_STACK
1298
         if(hfvl->size()==1)
1299
         {
1300
            if(!mReason)
1301
            {
1302
               mReason=new Data;
1303
            }
1304
            
1305
            if(mInvalid)
1306
            {
1307
               mReason->append(",",1);
1308
            }
1309
            mInvalid=true;
1310
            mReason->append("Multiple values in single-value header ",39);
1311
            (*mReason)+=Headers::getHeaderName(header);
1312
            return;
1313
         }
1314
#endif
1315
70.3k
         if (hfvl->empty())
1316
880
         {
1317
880
            hfvl->push_back(start ? start : Data::Empty.data(), len, false);
1318
880
         }
1319
70.3k
      }
1320
1321
664k
   }
1322
775k
   else
1323
775k
   {
1324
775k
      resip_assert(headerLen >= 0);
1325
775k
      for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
1326
9.70M
           i != mUnknownHeaders.end(); i++)
1327
9.69M
      {
1328
9.69M
         if (i->first.size() == (unsigned int)headerLen &&
1329
1.94M
             strncasecmp(i->first.data(), headerName, headerLen) == 0)
1330
763k
         {
1331
            // add to end of list
1332
763k
            if (len)
1333
119k
            {
1334
119k
               i->second->push_back(start, len, false);
1335
119k
            }
1336
763k
            return;
1337
763k
         }
1338
9.69M
      }
1339
1340
      // didn't find it, add an entry
1341
12.0k
      HeaderFieldValueList *hfvs = getEmptyHfvl();
1342
12.0k
      if (len)
1343
4.00k
      {
1344
4.00k
         hfvs->push_back(start, len, false);
1345
4.00k
      }
1346
12.0k
      mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(Data(headerName, headerLen),
1347
12.0k
                                                                  hfvs));
1348
12.0k
   }
1349
1.44M
}
1350
1351
RequestLine& 
1352
SipMessage::header(const RequestLineType& l)
1353
0
{
1354
0
   resip_assert (!isResponse());
1355
0
   if (mStartLine == 0 )
1356
0
   { 
1357
0
      mStartLine = new (mStartLineMem) RequestLine;
1358
0
      mRequest = true;
1359
0
   }
1360
0
   return *static_cast<RequestLine*>(mStartLine);
1361
0
}
1362
1363
const RequestLine& 
1364
SipMessage::header(const RequestLineType& l) const
1365
0
{
1366
0
   resip_assert (!isResponse());
1367
0
   if (mStartLine == 0 )
1368
0
   { 
1369
      // request line missing
1370
0
      resip_assert(false);
1371
0
   }
1372
0
   return *static_cast<RequestLine*>(mStartLine);
1373
0
}
1374
1375
StatusLine& 
1376
SipMessage::header(const StatusLineType& l)
1377
0
{
1378
0
   resip_assert (!isRequest());
1379
0
   if (mStartLine == 0 )
1380
0
   { 
1381
0
      mStartLine = new (mStartLineMem) StatusLine;
1382
0
      mResponse = true;
1383
0
   }
1384
0
   return *static_cast<StatusLine*>(mStartLine);
1385
0
}
1386
1387
const StatusLine& 
1388
SipMessage::header(const StatusLineType& l) const
1389
0
{
1390
0
   resip_assert (!isRequest());
1391
0
   if (mStartLine == 0 )
1392
0
   { 
1393
      // status line missing
1394
0
      resip_assert(false);
1395
0
   }
1396
0
   return *static_cast<StatusLine*>(mStartLine);
1397
0
}
1398
1399
HeaderFieldValueList* 
1400
SipMessage::ensureHeaders(Headers::Type type)
1401
665k
{
1402
665k
   return mKnownHeaders.insert(type, [this] { return getEmptyHfvl(); })->getValues();
1403
665k
}
1404
1405
HeaderFieldValueList*
1406
SipMessage::ensureHeaders(Headers::Type type) const
1407
8.95k
{
1408
8.95k
   auto it = mKnownHeaders.find(type);
1409
8.95k
   if (it == mKnownHeaders.end())
1410
0
   {
1411
0
      throwHeaderMissing(type);
1412
0
   }
1413
8.95k
   return it->getValues();
1414
8.95k
}
1415
1416
HeaderFieldValueList* 
1417
SipMessage::ensureHeader(Headers::Type type)
1418
231
{
1419
231
   HeaderFieldValueList* hfvl = ensureHeaders(type);
1420
231
   if (hfvl->empty())
1421
0
      hfvl->push_back(nullptr, 0, false);
1422
1423
231
   return hfvl;
1424
231
}
1425
1426
HeaderFieldValueList*
1427
SipMessage::ensureHeader(Headers::Type type) const
1428
8.95k
{
1429
8.95k
   HeaderFieldValueList* hfvl = ensureHeaders(type);
1430
8.95k
   if (hfvl->empty())
1431
0
      hfvl->push_back(nullptr, 0, false);
1432
1433
8.95k
   return hfvl;
1434
8.95k
}
1435
1436
void
1437
SipMessage::throwHeaderMissing(Headers::Type type) const
1438
0
{
1439
   // header missing
1440
   // assert(false);
1441
0
   InfoLog( << "Missing Header [" << Headers::getHeaderName(type) << "]");      
1442
0
   DebugLog (<< *this);
1443
0
   throw Exception("Missing header " + Headers::getHeaderName(type), __FILE__, __LINE__);
1444
0
}
1445
1446
// type safe header accessors
1447
bool    
1448
SipMessage::exists(const HeaderBase& headerType) const 
1449
9.30k
{
1450
9.30k
   return mKnownHeaders.find(headerType.getTypeNum()) != mKnownHeaders.end();
1451
9.30k
};
1452
1453
bool
1454
SipMessage::empty(const HeaderBase& headerType) const
1455
0
{
1456
0
   auto it = mKnownHeaders.find(headerType.getTypeNum());
1457
0
   return it == mKnownHeaders.end() || it->getValues()->parsedEmpty();
1458
0
}
1459
1460
void
1461
SipMessage::remove(Headers::Type type)
1462
0
{
1463
0
   auto it = mKnownHeaders.find(type);
1464
0
   if (it != mKnownHeaders.end())
1465
0
      mKnownHeaders.erase(it);
1466
0
};
1467
1468
#ifndef PARTIAL_TEMPLATE_SPECIALIZATION
1469
1470
#undef defineHeader
1471
#define defineHeader(_header, _name, _type, _rfc)                                                       \
1472
const H_##_header::Type&                                                                                \
1473
8.95k
SipMessage::header(const H_##_header& headerType) const                                                 \
1474
8.95k
{                                                                                                       \
1475
8.95k
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1476
8.95k
   if (hfvs->getParserContainer() == 0)                                                                 \
1477
8.95k
   {                                                                                                    \
1478
265
      SipMessage* nc_this(const_cast<SipMessage*>(this)); \
1479
265
      hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1480
265
   }                                                                                                    \
1481
8.95k
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1482
8.95k
}                                                                                                       \
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentDisposition const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentEncoding const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_MIMEVersion const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Priority const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Event const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SubscriptionState const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SIPETag const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SIPIfMatch const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentId const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReferSub const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_AnswerMode const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PrivAnswerMode const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentType const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_IdentityInfo const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_From const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_To const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReplyTo const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReferTo const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReferredBy const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PCalledPartyId const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentTransferEncoding const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Organization const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketKey const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketKey1 const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketKey2 const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Origin const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Host const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketAccept const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Server const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Subject const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_UserAgent const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Timestamp const&) const
resip::SipMessage::header(resip::H_ContentLength const&) const
Line
Count
Source
1473
8.95k
SipMessage::header(const H_##_header& headerType) const                                                 \
1474
8.95k
{                                                                                                       \
1475
8.95k
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1476
8.95k
   if (hfvs->getParserContainer() == 0)                                                                 \
1477
8.95k
   {                                                                                                    \
1478
265
      SipMessage* nc_this(const_cast<SipMessage*>(this)); \
1479
265
      hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1480
265
   }                                                                                                    \
1481
8.95k
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1482
8.95k
}                                                                                                       \
Unexecuted instantiation: resip::SipMessage::header(resip::H_MaxForwards const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_MinExpires const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_RSeq const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_RetryAfter const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_FlowTimer const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Expires const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SessionExpires const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_MinSE const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_CallID const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Replaces const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_InReplyTo const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Join const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_TargetDialog const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_AuthenticationInfo const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_CSeq const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Date const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_RAck const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PChargingVector const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PChargingFunctionAddresses const&) const
1483
                                                                                                        \
1484
H_##_header::Type&                                                                                      \
1485
231
SipMessage::header(const H_##_header& headerType)                                                       \
1486
231
{                                                                                                       \
1487
231
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1488
231
   if (hfvs->getParserContainer() == 0)                                                                 \
1489
231
   {                                                                                                    \
1490
0
      hfvs->setParserContainer(makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1491
0
   }                                                                                                    \
1492
231
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1493
231
}
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentDisposition const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentEncoding const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_MIMEVersion const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Priority const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Event const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SubscriptionState const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SIPETag const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SIPIfMatch const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentId const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReferSub const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_AnswerMode const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PrivAnswerMode const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentType const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_IdentityInfo const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_From const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_To const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReplyTo const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReferTo const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ReferredBy const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PCalledPartyId const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentTransferEncoding const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Organization const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketKey const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketKey1 const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketKey2 const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Origin const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Host const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecWebSocketAccept const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Server const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Subject const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_UserAgent const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Timestamp const&)
resip::SipMessage::header(resip::H_ContentLength const&)
Line
Count
Source
1485
231
SipMessage::header(const H_##_header& headerType)                                                       \
1486
231
{                                                                                                       \
1487
231
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1488
231
   if (hfvs->getParserContainer() == 0)                                                                 \
1489
231
   {                                                                                                    \
1490
0
      hfvs->setParserContainer(makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1491
0
   }                                                                                                    \
1492
231
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1493
231
}
Unexecuted instantiation: resip::SipMessage::header(resip::H_MaxForwards const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_MinExpires const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_RSeq const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_RetryAfter const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_FlowTimer const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Expires const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SessionExpires const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_MinSE const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_CallID const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Replaces const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_InReplyTo const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Join const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_TargetDialog const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_AuthenticationInfo const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_CSeq const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Date const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_RAck const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PChargingVector const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PChargingFunctionAddresses const&)
1494
1495
#undef defineMultiHeader
1496
#define defineMultiHeader(_header, _name, _type, _rfc)                                          \
1497
const H_##_header##s::Type&                                                                     \
1498
0
SipMessage::header(const H_##_header##s& headerType) const                                      \
1499
0
{                                                                                               \
1500
0
   HeaderFieldValueList* hfvs = ensureHeaders(headerType.getTypeNum());                  \
1501
0
   if (hfvs->getParserContainer() == 0)                                                         \
1502
0
   {                                                                                            \
1503
0
      SipMessage* nc_this(const_cast<SipMessage*>(this)); \
1504
0
      hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header##s::ContainedType>(hfvs, headerType.getTypeNum()));        \
1505
0
   }                                                                                            \
1506
0
   return *static_cast<H_##_header##s::Type*>(hfvs->getParserContainer());                     \
1507
0
}                                                                                               \
Unexecuted instantiation: resip::SipMessage::header(resip::H_AllowEventss const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Identitys const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_AcceptEncodings const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_AcceptLanguages const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Allows const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentLanguages const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ProxyRequires const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Requires const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Supporteds const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Unsupporteds const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecurityClients const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecurityServers const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecurityVerifys const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_RequestDispositions const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Reasons const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Privacys const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PMediaAuthorizations const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Accepts const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_CallInfos const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_AlertInfos const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ErrorInfos const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_RecordRoutes const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Routes const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Contacts const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Paths const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_AcceptContacts const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_RejectContacts const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PAssertedIdentitys const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PPreferredIdentitys const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PAssociatedUris const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ServiceRoutes const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Cookies const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Authorizations const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ProxyAuthenticates const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_ProxyAuthorizations const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_WWWAuthenticates const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Warnings const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_Vias const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_RemotePartyIds const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_HistoryInfos const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PAccessNetworkInfos const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_PVisitedNetworkIDs const&) const
Unexecuted instantiation: resip::SipMessage::header(resip::H_UserToUsers const&) const
1508
                                                                                                \
1509
H_##_header##s::Type&                                                                           \
1510
0
SipMessage::header(const H_##_header##s& headerType)                                            \
1511
0
{                                                                                               \
1512
0
   HeaderFieldValueList* hfvs = ensureHeaders(headerType.getTypeNum());                  \
1513
0
   if (hfvs->getParserContainer() == 0)                                                         \
1514
0
   {                                                                                            \
1515
0
      hfvs->setParserContainer(makeParserContainer<H_##_header##s::ContainedType>(hfvs, headerType.getTypeNum()));        \
1516
0
   }                                                                                            \
1517
0
   return *static_cast<H_##_header##s::Type*>(hfvs->getParserContainer());                     \
1518
0
}
Unexecuted instantiation: resip::SipMessage::header(resip::H_AllowEventss const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Identitys const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_AcceptEncodings const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_AcceptLanguages const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Allows const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ContentLanguages const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ProxyRequires const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Requires const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Supporteds const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Unsupporteds const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecurityClients const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecurityServers const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_SecurityVerifys const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_RequestDispositions const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Reasons const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Privacys const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PMediaAuthorizations const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Accepts const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_CallInfos const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_AlertInfos const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ErrorInfos const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_RecordRoutes const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Routes const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Contacts const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Paths const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_AcceptContacts const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_RejectContacts const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PAssertedIdentitys const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PPreferredIdentitys const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PAssociatedUris const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ServiceRoutes const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Cookies const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Authorizations const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ProxyAuthenticates const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_ProxyAuthorizations const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_WWWAuthenticates const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Warnings const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_Vias const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_RemotePartyIds const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_HistoryInfos const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PAccessNetworkInfos const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_PVisitedNetworkIDs const&)
Unexecuted instantiation: resip::SipMessage::header(resip::H_UserToUsers const&)
1519
1520
defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261");
1521
defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261");
1522
defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261");
1523
defineHeader(Priority, "Priority", Token, "RFC 3261");
1524
defineHeader(Event, "Event", Token, "RFC 3265");
1525
defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265");
1526
defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903");
1527
defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903");
1528
defineHeader(ContentId, "Content-ID", Token, "RFC 2045");
1529
defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265");
1530
defineMultiHeader(Identity, "Identity", StringCategory, "RFC 8224");   // Originally defined in RFC 4474 as a single header, but later modified by RFC8224 to be a multiheader
1531
defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261");
1532
defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261");
1533
defineMultiHeader(Allow, "Allow", Token, "RFC 3261");
1534
defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261");
1535
defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261");
1536
defineMultiHeader(Require, "Require", Token, "RFC 3261");
1537
defineMultiHeader(Supported, "Supported", Token, "RFC 3261");
1538
defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261");
1539
defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329");
1540
defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329");
1541
defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329");
1542
defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841");
1543
defineMultiHeader(Reason, "Reason", Token, "RFC 3326");
1544
defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323");
1545
defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313");
1546
defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488");
1547
defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01");
1548
defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01");
1549
1550
defineMultiHeader(Accept, "Accept", Mime, "RFC 3261");
1551
defineHeader(ContentType, "Content-Type", Mime, "RFC 3261");
1552
1553
defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261");
1554
defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261");
1555
defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261");
1556
defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474");
1557
1558
defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261");
1559
defineMultiHeader(Route, "Route", NameAddr, "RFC 3261");
1560
defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261");
1561
defineHeader(From, "From", NameAddr, "RFC 3261");
1562
defineHeader(To, "To", NameAddr, "RFC 3261");
1563
defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261");
1564
defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515");
1565
defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892");
1566
defineMultiHeader(Path, "Path", NameAddr, "RFC 3327");
1567
defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841");
1568
defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841");
1569
defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325");
1570
defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325");
1571
defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455");
1572
defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455");
1573
defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608");
1574
1575
defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?");
1576
defineHeader(Organization, "Organization", StringCategory, "RFC 3261");
1577
defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455");
1578
defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76");
1579
defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76");
1580
defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76");
1581
defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76");
1582
defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455");
1583
defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265");
1584
defineHeader(Server, "Server", StringCategory, "RFC 3261");
1585
defineHeader(Subject, "Subject", StringCategory, "RFC 3261");
1586
defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261");
1587
defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261");
1588
1589
defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261");
1590
defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261");
1591
defineHeader(MinExpires, "Min-Expires", Uint32Category, "RFC 3261");
1592
defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261");
1593
1594
// !dlb! this one is not quite right -- can have (comment) after field value
1595
defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261");
1596
defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626");
1597
1598
defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261");
1599
defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028");
1600
defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028");
1601
1602
defineHeader(CallID, "Call-ID", CallID, "RFC 3261");
1603
defineHeader(Replaces, "Replaces", CallID, "RFC 3891");
1604
defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261");
1605
defineHeader(Join, "Join", CallId, "RFC 3911");
1606
defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538");
1607
1608
defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261");
1609
defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261");
1610
defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261");
1611
defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261");
1612
defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261");
1613
1614
defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261");
1615
defineHeader(Date, "Date", DateCategory, "RFC 3261");
1616
defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261");
1617
defineMultiHeader(Via, "Via", Via, "RFC 3261");
1618
defineHeader(RAck, "RAck", RAckCategory, "RFC 3262");
1619
defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep?
1620
defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244");
1621
1622
defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"); // section 5.4.
1623
defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455");
1624
defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455");
1625
defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455");
1626
1627
defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17");
1628
1629
#endif
1630
1631
const HeaderFieldValueList*
1632
SipMessage::getRawHeader(Headers::Type headerType) const
1633
0
{
1634
0
   auto it = mKnownHeaders.find(headerType);
1635
0
   if (it != mKnownHeaders.end())
1636
0
   {
1637
0
      return it->getValues();
1638
0
   }
1639
1640
0
   return nullptr;
1641
0
}
1642
1643
void
1644
SipMessage::setRawHeader(const HeaderFieldValueList* hfvs, Headers::Type headerType)
1645
0
{
1646
0
   auto it = mKnownHeaders.find(headerType);
1647
0
   if (it != mKnownHeaders.end())
1648
0
   {
1649
0
      *it->getValues() = *hfvs;
1650
0
   }
1651
0
   else
1652
0
   {
1653
0
      bool constructed = false;
1654
0
      it = mKnownHeaders.insert(headerType, [&]
1655
0
      {
1656
0
         constructed = true;
1657
0
         return getCopyHfvl(*hfvs);
1658
0
      });
1659
0
      if (!constructed)
1660
0
      {
1661
         // A previously erased element was reused
1662
0
         *it->getValues() = *hfvs;
1663
0
      }
1664
0
   }
1665
1666
0
   if(!Headers::isMulti(headerType) && it->getValues()->parsedEmpty())
1667
0
   {
1668
0
      it->getValues()->push_back(nullptr, 0, false);
1669
0
   }
1670
0
}
1671
1672
void
1673
SipMessage::setForceTarget(const Uri& uri)
1674
0
{
1675
0
   if (mForceTarget)
1676
0
   {
1677
0
      *mForceTarget = uri;
1678
0
   }
1679
0
   else
1680
0
   {
1681
0
      mForceTarget = new Uri(uri);
1682
0
   }
1683
0
}
1684
1685
void
1686
SipMessage::clearForceTarget()
1687
0
{
1688
0
   delete mForceTarget;
1689
0
   mForceTarget = 0;
1690
0
}
1691
1692
const Uri&
1693
SipMessage::getForceTarget() const
1694
0
{
1695
0
   resip_assert(mForceTarget);
1696
0
   return *mForceTarget;
1697
0
}
1698
1699
bool
1700
SipMessage::hasForceTarget() const
1701
0
{
1702
0
   return (mForceTarget != 0);
1703
0
}
1704
1705
SipMessage& 
1706
SipMessage::mergeUri(const Uri& source)
1707
0
{
1708
0
   header(h_RequestLine).uri() = source;
1709
0
   header(h_RequestLine).uri().removeEmbedded();
1710
1711
0
   if (source.exists(p_method))
1712
0
   {
1713
0
      header(h_RequestLine).method() = getMethodType(source.param(p_method));
1714
0
      header(h_RequestLine).uri().remove(p_method);      
1715
0
   }           
1716
   
1717
   //19.1.5
1718
   //dangerous headers not included in merge:
1719
   // From, Call-ID, Cseq, Via, Record Route, Route, Accept, Accept-Encoding,
1720
   // Accept-Langauge, Allow, Contact, Organization, Supported, User-Agent
1721
1722
   //from the should-verify section, remove for now, some never seem to make
1723
   //sense:  
1724
   // Content-Encoding, Content-Language, Content-Length, Content-Type, Date,
1725
   // Mime-Version, and TimeStamp
1726
1727
0
   if (source.hasEmbedded())
1728
0
   {
1729
0
      h_AuthenticationInfo.merge(*this, source.embedded());
1730
0
      h_ContentTransferEncoding.merge(*this, source.embedded());
1731
0
      h_Event.merge(*this, source.embedded());
1732
0
      h_Expires.merge(*this, source.embedded());
1733
0
      h_SessionExpires.merge(*this, source.embedded());
1734
0
      h_MinSE.merge(*this, source.embedded());
1735
0
      h_InReplyTo.merge(*this, source.embedded());
1736
0
      h_MaxForwards.merge(*this, source.embedded());
1737
0
      h_MinExpires.merge(*this, source.embedded());
1738
0
      h_Priority.merge(*this, source.embedded());
1739
0
      h_ReferTo.merge(*this, source.embedded());
1740
0
      h_ReferredBy.merge(*this, source.embedded());
1741
0
      h_Replaces.merge(*this, source.embedded());
1742
0
      h_ReplyTo.merge(*this, source.embedded());
1743
0
      h_RetryAfter.merge(*this, source.embedded());
1744
0
      h_Server.merge(*this, source.embedded());
1745
0
      h_SIPETag.merge(*this, source.embedded());
1746
0
      h_SIPIfMatch.merge(*this, source.embedded());
1747
0
      h_Subject.merge(*this, source.embedded());
1748
0
      h_SubscriptionState.merge(*this, source.embedded());
1749
0
      h_To.merge(*this, source.embedded());
1750
0
      h_Warnings.merge(*this, source.embedded());
1751
1752
0
      h_SecurityClients.merge(*this, source.embedded());
1753
0
      h_SecurityServers.merge(*this, source.embedded());
1754
0
      h_SecurityVerifys.merge(*this, source.embedded());
1755
1756
0
      h_Authorizations.merge(*this, source.embedded());
1757
0
      h_ProxyAuthenticates.merge(*this, source.embedded());
1758
0
      h_WWWAuthenticates.merge(*this, source.embedded());
1759
0
      h_ProxyAuthorizations.merge(*this, source.embedded());
1760
1761
0
      h_AlertInfos.merge(*this, source.embedded());
1762
0
      h_AllowEvents.merge(*this, source.embedded());
1763
0
      h_CallInfos.merge(*this, source.embedded());
1764
0
      h_ErrorInfos.merge(*this, source.embedded());
1765
0
      h_ProxyRequires.merge(*this, source.embedded());
1766
0
      h_Requires.merge(*this, source.embedded());
1767
0
      h_Unsupporteds.merge(*this, source.embedded());
1768
0
      h_AnswerMode.merge(*this, source.embedded());
1769
0
      h_PrivAnswerMode.merge(*this, source.embedded());
1770
1771
0
      h_RSeq.merge(*this, source.embedded());
1772
0
      h_RAck.merge(*this, source.embedded());
1773
0
   }   
1774
   //unknown header merge
1775
0
   return *this;   
1776
0
}
1777
1778
void 
1779
SipMessage::setSecurityAttributes(std::unique_ptr<SecurityAttributes> sec) noexcept
1780
0
{
1781
0
   mSecurityAttributes = std::move(sec);
1782
0
}
1783
1784
void
1785
SipMessage::callOutboundDecorators(const Tuple& src,
1786
                                   const Tuple& dest,
1787
                                   const Data& sigcompId)
1788
0
{
1789
0
   rollbackOutboundDecorators();
1790
1791
0
   std::vector<MessageDecorator*>::iterator i;
1792
0
   for (i = mOutboundDecorators.begin(); i != mOutboundDecorators.end(); i++)
1793
0
   {
1794
0
      (*i)->decorateMessage(*this, src, dest, sigcompId);
1795
0
   }
1796
0
   mIsDecorated = true;
1797
0
}
1798
1799
void 
1800
SipMessage::clearOutboundDecorators()
1801
0
{
1802
0
   rollbackOutboundDecorators();
1803
1804
0
   while(!mOutboundDecorators.empty())
1805
0
   {
1806
0
      delete mOutboundDecorators.back();
1807
0
      mOutboundDecorators.pop_back();
1808
0
   }
1809
0
}
1810
1811
void 
1812
SipMessage::rollbackOutboundDecorators()
1813
0
{
1814
0
   if (mIsDecorated)
1815
0
   {
1816
0
      std::vector<MessageDecorator*>::reverse_iterator r;
1817
0
      for (r = mOutboundDecorators.rbegin(); r != mOutboundDecorators.rend(); ++r)
1818
0
      {
1819
0
         (*r)->rollbackMessage(*this);
1820
0
      }
1821
0
      mIsDecorated = false;
1822
0
   }
1823
0
}
1824
1825
void 
1826
SipMessage::copyOutboundDecoratorsToStackCancel(SipMessage& cancel)
1827
0
{
1828
0
  std::vector<MessageDecorator*>::iterator i;
1829
0
  for (i = mOutboundDecorators.begin();
1830
0
       i != mOutboundDecorators.end(); i++)
1831
0
  {
1832
0
     if((*i)->copyToStackCancels())
1833
0
     {
1834
0
        cancel.addOutboundDecorator(std::unique_ptr<MessageDecorator>((*i)->clone()));
1835
0
     }    
1836
0
  }
1837
0
}
1838
1839
void 
1840
SipMessage::copyOutboundDecoratorsToStackFailureAck(SipMessage& ack)
1841
0
{
1842
0
  std::vector<MessageDecorator*>::iterator i;
1843
0
  for (i = mOutboundDecorators.begin();
1844
0
       i != mOutboundDecorators.end(); i++)
1845
0
  {
1846
0
     if((*i)->copyToStackFailureAcks())
1847
0
     {
1848
0
        ack.addOutboundDecorator(std::unique_ptr<MessageDecorator>((*i)->clone()));
1849
0
     }    
1850
0
  }
1851
0
}
1852
1853
/* ====================================================================
1854
 * The Vovida Software License, Version 1.0 
1855
 * 
1856
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
1857
 * 
1858
 * Redistribution and use in source and binary forms, with or without
1859
 * modification, are permitted provided that the following conditions
1860
 * are met:
1861
 * 
1862
 * 1. Redistributions of source code must retain the above copyright
1863
 *    notice, this list of conditions and the following disclaimer.
1864
 * 
1865
 * 2. Redistributions in binary form must reproduce the above copyright
1866
 *    notice, this list of conditions and the following disclaimer in
1867
 *    the documentation and/or other materials provided with the
1868
 *    distribution.
1869
 * 
1870
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1871
 *    and "Vovida Open Communication Application Library (VOCAL)" must
1872
 *    not be used to endorse or promote products derived from this
1873
 *    software without prior written permission. For written
1874
 *    permission, please contact vocal@vovida.org.
1875
 *
1876
 * 4. Products derived from this software may not be called "VOCAL", nor
1877
 *    may "VOCAL" appear in their name, without prior written
1878
 *    permission of Vovida Networks, Inc.
1879
 * 
1880
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1881
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1882
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1883
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
1884
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1885
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1886
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1887
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1888
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1889
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1890
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1891
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1892
 * DAMAGE.
1893
 * 
1894
 * ====================================================================
1895
 * 
1896
 * This software consists of voluntary contributions made by Vovida
1897
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1898
 * Inc.  For more information on Vovida Networks, Inc., please see
1899
 * <http://www.vovida.org/>.
1900
 *
1901
 * vi: set shiftwidth=3 expandtab:
1902
 */