Coverage Report

Created: 2026-09-14 06:22

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