Coverage Report

Created: 2026-02-13 06:31

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