Coverage Report

Created: 2024-04-23 06:04

/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
   : mIsDecorated(false),
33
     mIsBadAck200(false),     
34
     mIsExternal(receivedTransportTuple != 0),  // may be modified later by setFromTU or setFromExternal
35
     mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)),
36
#ifndef __SUNPRO_CC
37
     mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)),
38
#else
39
     mUnknownHeaders(),
40
#endif
41
     mRequest(false),
42
     mResponse(false),
43
     mInvalid(false),
44
     mCreatedTime(Timer::getTimeMicroSec()),
45
     mTlsDomain(Data::Empty)
46
9.86k
{
47
9.86k
   if(receivedTransportTuple)
48
0
   {
49
0
       mReceivedTransportTuple = *receivedTransportTuple;
50
0
   }
51
   // !bwc! TODO make this tunable
52
9.86k
   mHeaders.reserve(16);
53
9.86k
   clear();
54
9.86k
}
55
56
SipMessage::SipMessage(const SipMessage& from)
57
   : mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)),
58
#ifndef __SUNPRO_CC
59
     mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)),
60
#else
61
     mUnknownHeaders(),
62
#endif
63
     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.86k
{
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.86k
   freeMem();
101
9.86k
}
102
103
void
104
SipMessage::clear(bool leaveResponseStuff)
105
9.86k
{
106
9.86k
   if(!leaveResponseStuff)
107
9.86k
   {
108
9.86k
      memset(mHeaderIndices,0,sizeof(mHeaderIndices));
109
9.86k
      clearHeaders();
110
      
111
      // !bwc! The "invalid" 0 index.
112
9.86k
      mHeaders.push_back(getEmptyHfvl());
113
9.86k
      mBufferList.clear();
114
9.86k
   }
115
116
9.86k
   mUnknownHeaders.clear();
117
118
9.86k
   mStartLine = 0;
119
9.86k
   mContents = 0;
120
9.86k
   mContentsHfv.clear();
121
9.86k
   mForceTarget = 0;
122
9.86k
   mReason=0;
123
9.86k
   mOutboundDecorators.clear();
124
9.86k
}
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.86k
{
226
9.86k
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
227
20.4k
        i != mUnknownHeaders.end(); i++)
228
10.6k
   {
229
10.6k
      freeHfvl(i->second);
230
10.6k
   }
231
232
9.86k
   if(!leaveResponseStuff)
233
9.86k
   {
234
9.86k
      clearHeaders();
235
236
9.86k
      for (vector<char*>::iterator i = mBufferList.begin();
237
1.35M
           i != mBufferList.end(); i++)
238
1.34M
      {
239
1.34M
         delete [] *i;
240
1.34M
      }
241
9.86k
   }
242
243
9.86k
   if(mStartLine)
244
547
   {
245
547
      mStartLine->~StartLine();
246
547
      mStartLine=0;
247
547
   }
248
249
9.86k
   delete mContents;
250
9.86k
   delete mForceTarget;
251
9.86k
   delete mReason;
252
253
9.86k
   for(std::vector<MessageDecorator*>::iterator i=mOutboundDecorators.begin();
254
9.86k
         i!=mOutboundDecorators.end();++i)
255
0
   {
256
0
      delete *i;
257
0
   }
258
9.86k
}
259
260
void
261
SipMessage::clearHeaders()
262
19.7k
{
263
30.6k
    for (TypedHeaders::iterator i = mHeaders.begin(); i != mHeaders.end(); i++)
264
10.8k
    {
265
10.8k
        freeHfvl(*i);
266
10.8k
    }
267
19.7k
    mHeaders.clear();
268
19.7k
}
269
270
SipMessage*
271
SipMessage::make(const Data& data, bool isExternal)
272
6.45k
{
273
6.45k
   Tuple fakeWireTuple;
274
6.45k
   fakeWireTuple.setType(UDP);
275
6.45k
   SipMessage* msg = new SipMessage(isExternal ? &fakeWireTuple : 0);
276
277
6.45k
   size_t len = data.size();
278
6.45k
   char *buffer = new char[len + 5];
279
280
6.45k
   msg->addBuffer(buffer);
281
6.45k
   memcpy(buffer,data.data(), len);
282
6.45k
   MsgHeaderScanner msgHeaderScanner;
283
6.45k
   msgHeaderScanner.prepareForMessage(msg);
284
   
285
6.45k
   char *unprocessedCharPtr;
286
6.45k
   if (msgHeaderScanner.scanChunk(buffer, (unsigned int)len, &unprocessedCharPtr) != MsgHeaderScanner::scrEnd)
287
6.33k
   {
288
6.33k
      DebugLog(<<"Scanner rejecting buffer as unparsable / fragmented.");
289
6.33k
      DebugLog(<< data);
290
6.33k
      delete msg; 
291
6.33k
      msg = 0; 
292
6.33k
      return 0;
293
6.33k
   }
294
295
   // no pp error
296
115
   unsigned int used = (unsigned int)(unprocessedCharPtr - buffer);
297
298
115
   if (used < len)
299
113
   {
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
113
      msg->setBody(buffer+used,uint32_t(len-used));
308
      //DebugLog(<<"added " << len-used << " byte body");
309
113
   }
310
311
115
   return msg;
312
6.45k
}
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.34M
{
866
1.34M
   mBufferList.push_back(buf);
867
1.34M
}
868
869
void 
870
SipMessage::setStartLine(const char* st, int len)
871
547
{
872
547
   if(len >= 4 && !strncasecmp(st,"SIP/",4))
873
2
   {
874
      // Response
875
2
      mStartLine = new (mStartLineMem) StatusLine(st, len);
876
      //!dcm! should invoke the statusline parser here once it does limited validation
877
2
      mResponse = true;
878
2
   }
879
545
   else
880
545
   {
881
      // Request
882
545
      mStartLine = new (mStartLineMem) RequestLine(st, len);
883
      //!dcm! should invoke the responseline parser here once it does limited validation
884
545
      mRequest = true;
885
545
   }
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
547
}
913
914
void 
915
SipMessage::setBody(const char* start, uint32_t len)
916
27.3k
{
917
27.3k
   if(checkContentLength)
918
27.3k
   {
919
27.3k
      if(exists(h_ContentLength))
920
24.8k
      {
921
24.8k
         try
922
24.8k
         {
923
24.8k
            const_header(h_ContentLength).checkParsed();
924
24.8k
         }
925
24.8k
         catch(resip::ParseException& e)
926
24.8k
         {
927
84
            if(!mReason)
928
84
            {
929
84
               mReason=new Data;
930
84
            }
931
            
932
84
            if(mInvalid)
933
0
            {
934
0
               mReason->append(",",1);
935
0
            }
936
937
84
            mInvalid=true; 
938
84
            mReason->append("Malformed Content-Length",24);
939
84
            InfoLog(<< "Malformed Content-Length. Ignoring. " << e);
940
84
            header(h_ContentLength).value()=len;
941
84
         }
942
         
943
24.8k
         uint32_t contentLength=const_header(h_ContentLength).value();
944
         
945
24.8k
         if(len > contentLength)
946
3.42k
         {
947
3.42k
            InfoLog(<< (len-contentLength) << " extra bytes after body. Ignoring these bytes.");
948
3.42k
         }
949
21.3k
         else if(len < contentLength)
950
91
         {
951
91
            InfoLog(<< "Content Length (" << contentLength << ") is "
952
91
                    << (contentLength-len) << " bytes larger than body (" << len << ")!"
953
91
                    << " (We are supposed to 400 this) ");
954
955
91
            if(!mReason)
956
60
            {
957
60
               mReason=new Data;
958
60
            }
959
960
91
            if(mInvalid)
961
31
            {
962
31
               mReason->append(",",1);
963
31
            }
964
965
91
            mInvalid=true; 
966
91
            mReason->append("Bad Content-Length (larger than datagram)",41);
967
91
            header(h_ContentLength).value()=len;
968
91
            contentLength=len;
969
                     
970
91
         }
971
         
972
24.8k
         mContentsHfv.init(start,contentLength, false);
973
24.8k
      }
974
2.57k
      else
975
2.57k
      {
976
2.57k
         InfoLog(<< "Message has a body, but no Content-Length header.");
977
2.57k
         mContentsHfv.init(start,len, false);
978
2.57k
      }
979
27.3k
   }
980
0
   else
981
0
   {
982
0
      mContentsHfv.init(start,len, false);
983
0
   }
984
27.3k
}
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.88M
{
1204
1.88M
   if (header != Headers::UNKNOWN)
1205
1.00M
   {
1206
1.00M
      resip_assert(header >= Headers::UNKNOWN && header < Headers::MAX_HEADERS);
1207
1.00M
      HeaderFieldValueList* hfvl=0;
1208
1.00M
      if (mHeaderIndices[header] == 0)
1209
1.03k
      {
1210
1.03k
         mHeaderIndices[header] = (short)mHeaders.size();
1211
1.03k
         mHeaders.push_back(getEmptyHfvl());
1212
1.03k
         hfvl=mHeaders.back();
1213
1.03k
      }
1214
1.00M
      else
1215
1.00M
      {
1216
1.00M
         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
1.00M
         hfvl=mHeaders[mHeaderIndices[header]];
1224
1.00M
      }
1225
1226
1.00M
      if(Headers::isMulti(header))
1227
668k
      {
1228
668k
         if (len)
1229
569k
         {
1230
569k
            hfvl->push_back(start, len, false);
1231
569k
         }
1232
668k
      }
1233
333k
      else
1234
333k
      {
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
333k
         if (hfvl->empty())
1254
712
         {
1255
712
            hfvl->push_back(start ? start : Data::Empty.data(), len, false);
1256
712
         }
1257
333k
      }
1258
1259
1.00M
   }
1260
880k
   else
1261
880k
   {
1262
880k
      resip_assert(headerLen >= 0);
1263
880k
      for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
1264
17.1M
           i != mUnknownHeaders.end(); i++)
1265
17.1M
      {
1266
17.1M
         if (i->first.size() == (unsigned int)headerLen &&
1267
17.1M
             strncasecmp(i->first.data(), headerName, headerLen) == 0)
1268
869k
         {
1269
            // add to end of list
1270
869k
            if (len)
1271
296k
            {
1272
296k
               i->second->push_back(start, len, false);
1273
296k
            }
1274
869k
            return;
1275
869k
         }
1276
17.1M
      }
1277
1278
      // didn't find it, add an entry
1279
10.6k
      HeaderFieldValueList *hfvs = getEmptyHfvl();
1280
10.6k
      if (len)
1281
3.71k
      {
1282
3.71k
         hfvs->push_back(start, len, false);
1283
3.71k
      }
1284
10.6k
      mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(Data(headerName, headerLen),
1285
10.6k
                                                                  hfvs));
1286
10.6k
   }
1287
1.88M
}
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
175
{
1366
175
   HeaderFieldValueList* hfvl=0;
1367
175
   if(mHeaderIndices[type]!=0)
1368
175
   {
1369
175
      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
175
      hfvl = mHeaders[mHeaderIndices[type]];
1379
175
   }
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
175
   return hfvl;
1390
175
}
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.3k
{
1406
27.3k
   return mHeaderIndices[headerType.getTypeNum()] > 0;
1407
27.3k
};
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
49.6k
SipMessage::header(const H_##_header& headerType) const                                                 \
1434
49.6k
{                                                                                                       \
1435
49.6k
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1436
49.6k
   if (hfvs->getParserContainer() == 0)                                                                 \
1437
49.6k
   {                                                                                                    \
1438
203
      SipMessage* nc_this(const_cast<SipMessage*>(this)); \
1439
203
      hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1440
203
   }                                                                                                    \
1441
49.6k
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1442
49.6k
}                                                                                                       \
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
49.6k
SipMessage::header(const H_##_header& headerType) const                                                 \
1434
49.6k
{                                                                                                       \
1435
49.6k
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1436
49.6k
   if (hfvs->getParserContainer() == 0)                                                                 \
1437
49.6k
   {                                                                                                    \
1438
203
      SipMessage* nc_this(const_cast<SipMessage*>(this)); \
1439
203
      hfvs->setParserContainer(nc_this->makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1440
203
   }                                                                                                    \
1441
49.6k
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1442
49.6k
}                                                                                                       \
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
175
SipMessage::header(const H_##_header& headerType)                                                       \
1446
175
{                                                                                                       \
1447
175
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1448
175
   if (hfvs->getParserContainer() == 0)                                                                 \
1449
175
   {                                                                                                    \
1450
0
      hfvs->setParserContainer(makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1451
0
   }                                                                                                    \
1452
175
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1453
175
}
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
175
SipMessage::header(const H_##_header& headerType)                                                       \
1446
175
{                                                                                                       \
1447
175
   HeaderFieldValueList* hfvs = ensureHeader(headerType.getTypeNum());                           \
1448
175
   if (hfvs->getParserContainer() == 0)                                                                 \
1449
175
   {                                                                                                    \
1450
0
      hfvs->setParserContainer(makeParserContainer<H_##_header::Type>(hfvs, headerType.getTypeNum()));  \
1451
0
   }                                                                                                    \
1452
175
   return static_cast<ParserContainer<H_##_header::Type>*>(hfvs->getParserContainer())->front();       \
1453
175
}
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
 */