Coverage Report

Created: 2025-03-17 06:21

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