reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
SipMessage.hxx
Go to the documentation of this file.
1#if !defined(RESIP_SIPMESSAGE_HXX)
2#define RESIP_SIPMESSAGE_HXX
3
4#include <sys/types.h>
5
6#include <cstddef>
7#include <list>
8#include <vector>
9#include <limits>
10#include <memory>
11#include <utility>
12#include <iterator>
13#include <type_traits>
14
21#include "resip/stack/Tuple.hxx"
22#include "resip/stack/Uri.hxx"
27#include "rutil/compat.hxx"
28#include "rutil/ResipAssert.h"
30#include "rutil/Data.hxx"
31#include "rutil/DinkyPool.hxx"
33#include "rutil/Timer.hxx"
35
36#if defined(_MSC_VER) && !defined(__clang__)
37#include <intrin.h>
38#pragma intrinsic(_BitScanForward)
39#if defined(_M_X64) || defined(_M_ARM64)
40#pragma intrinsic(_BitScanForward64)
41#endif
42#if defined(_M_IX86) || defined(_M_X64)
43#pragma intrinsic(_tzcnt_u32)
44#endif
45#if defined(_M_X64)
46#pragma intrinsic(_tzcnt_u64)
47#endif
48#endif
49
50namespace resip
51{
52
53class Contents;
54class ExtensionHeader;
55class SecurityAttributes;
56
175{
176 public:
178#ifndef __SUNPRO_CC
179 typedef std::list< std::pair<Data, HeaderFieldValueList*>, StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase > > UnknownHeaders;
180#else
181 typedef std::list< std::pair<Data, HeaderFieldValueList*> > UnknownHeaders;
182#endif
183
211 {
212 private:
214 using HeaderIndex = unsigned char;
216 static constexpr HeaderIndex InvalidHeaderIndex = static_cast<HeaderIndex>(-1);
217 static_assert(Headers::MAX_HEADERS <= InvalidHeaderIndex, "HeaderIndex type is too small to cover all SIP header types");
218
220 using UsedBitMaskWord = std::size_t;
222 static constexpr unsigned int UsedBitMaskWordBits = static_cast<unsigned int>(std::numeric_limits<UsedBitMaskWord>::digits);
224 static constexpr unsigned int UsedBitMaskWordCount = (static_cast<unsigned int>(Headers::MAX_HEADERS) + UsedBitMaskWordBits - 1u) / UsedBitMaskWordBits;
225
226 public:
229 {
230 friend class KnownHeaders;
231
232 private:
234 HeaderFieldValueList* mValues;
236 Headers::Type mType;
237
238 public:
239 constexpr HeaderInfo() noexcept : mValues(nullptr), mType(Headers::UNKNOWN) {}
240 explicit constexpr HeaderInfo(Headers::Type type, HeaderFieldValueList* values = nullptr) noexcept : mValues(values), mType(type) {}
241
244
248 void setValues(HeaderFieldValueList* values) noexcept { mValues = values; }
249
250 private:
252 void setType(Headers::Type type) noexcept { mType = type; }
253 };
254
255 private:
257 using TypedHeaders = std::vector<HeaderInfo, StlPoolAllocator<HeaderInfo, PoolBase> >;
258
260 template<typename AdoptedIterator>
261 class UsedIterator
262 {
263 friend class KnownHeaders;
264
265 public:
266 using iterator_category = std::forward_iterator_tag;
267 using difference_type = typename std::iterator_traits<AdoptedIterator>::difference_type;
268 using value_type = typename std::iterator_traits<AdoptedIterator>::value_type;
269 using reference = typename std::iterator_traits<AdoptedIterator>::reference;
270 using pointer = typename std::iterator_traits<AdoptedIterator>::pointer;
271
272 private:
274 AdoptedIterator mIterator;
276 AdoptedIterator mEnd;
277
278 public:
279 constexpr UsedIterator() noexcept : mIterator(), mEnd(mIterator) {}
280 UsedIterator(UsedIterator const&) = default;
281
283 template<
284 typename OtherAdoptedIterator1,
285 typename OtherAdoptedIterator2,
286 typename = typename std::enable_if<
287 std::is_constructible<AdoptedIterator, OtherAdoptedIterator1&&>::value && std::is_constructible<AdoptedIterator, OtherAdoptedIterator2&&>::value
288 >::type
289 >
290 explicit constexpr UsedIterator(OtherAdoptedIterator1&& iter, OtherAdoptedIterator2&& end)
291 noexcept(std::is_nothrow_constructible<AdoptedIterator, OtherAdoptedIterator1&&>::value &&
292 std::is_nothrow_constructible<AdoptedIterator, OtherAdoptedIterator2&&>::value) :
293 mIterator(std::forward<OtherAdoptedIterator1>(iter)),
295 {
296 }
297
299 template<
300 typename OtherAdoptedIterator,
301 typename = typename std::enable_if<
302 !std::is_same<OtherAdoptedIterator, AdoptedIterator>::value && std::is_constructible<AdoptedIterator, OtherAdoptedIterator const&>::value
303 >::type
304 >
305 constexpr UsedIterator(UsedIterator<OtherAdoptedIterator> const& that)
306 noexcept(std::is_nothrow_constructible<AdoptedIterator, OtherAdoptedIterator const&>::value) :
307 mIterator(that.mIterator),
308 mEnd(that.mEnd)
309 {
310 }
311
312 reference operator*() const noexcept { return *mIterator; }
313 pointer operator->() const noexcept { return mIterator.operator->(); }
314 UsedIterator& operator++() { increment(); return *this; }
315 UsedIterator operator++(int) { UsedIterator copy(*this); increment(); return copy; }
316
317 friend bool operator==(UsedIterator const& left, UsedIterator const& right) noexcept { return left.mIterator == right.mIterator; }
318 friend bool operator!=(UsedIterator const& left, UsedIterator const& right) noexcept { return !(left == right); }
319
320 private:
322 void increment() noexcept
323 {
324 ++mIterator;
325 advanceToNextUsedEntry();
326 }
327
329 void advanceToNextUsedEntry() noexcept
330 {
331 while (mIterator != mEnd && mIterator->getType() == Headers::UNKNOWN)
332 ++mIterator;
333 }
334 };
335
336 public:
339 using value_type = TypedHeaders::value_type;
340 using reference = TypedHeaders::reference;
341 using const_reference = TypedHeaders::const_reference;
342 using pointer = TypedHeaders::pointer;
343 using const_pointer = TypedHeaders::const_pointer;
344 using size_type = TypedHeaders::size_type;
345 using difference_type = TypedHeaders::difference_type;
346 using allocator_type = TypedHeaders::allocator_type;
347
350 {
351 friend class KnownHeaders;
352
353 public:
361
362 private:
364 class Iterator
365 {
366 friend class OrderedView;
367
368 public:
369 using iterator_category = std::forward_iterator_tag;
370 using difference_type = std::ptrdiff_t;
372 using reference = value_type const&;
373 using pointer = const value_type*;
374
375 private:
377
378 private:
380 const KnownHeaders* mKnownHeaders;
382 size_type mPos;
383
384 public:
385 constexpr Iterator() noexcept : mKnownHeaders(nullptr), mPos(0u) {}
386 Iterator(Iterator const&) = default;
387
389 explicit constexpr Iterator(const KnownHeaders* knownHeaders, size_type pos) noexcept :
390 mKnownHeaders(knownHeaders),
391 mPos(pos)
392 {
393 }
394
395 reference operator*() const noexcept { return dereference(); }
396 pointer operator->() const noexcept { return &dereference(); }
397 Iterator& operator++() { increment(); return *this; }
398 Iterator operator++(int) { Iterator copy(*this); increment(); return copy; }
399
400 friend bool operator==(Iterator const& left, Iterator const& right) noexcept
401 {
402 resip_assert(left.mKnownHeaders == right.mKnownHeaders);
403 return left.mPos == right.mPos;
404 }
405 friend bool operator!=(Iterator const& left, Iterator const& right) noexcept
406 {
407 resip_assert(left.mKnownHeaders == right.mKnownHeaders);
408 return left.mPos != right.mPos;
409 }
410
411 private:
413 reference dereference() const noexcept
414 {
415 resip_assert(mKnownHeaders != nullptr);
416 return mKnownHeaders->mHeaders[mKnownHeaders->mHeaderIndices[mPos]];
417 }
418
420 void increment() noexcept
421 {
423 ++mPos;
424 advanceToNextUsedEntry();
425 }
426
427#if defined(_MSC_VER) && !defined(__clang__)
428#pragma warning(push)
429// unary minus operator applied to unsigned type, result still unsigned
430#pragma warning(disable: 4146)
431#endif
432
434 void advanceToNextUsedEntry() noexcept
435 {
436 resip_assert(mKnownHeaders != nullptr);
437
438 size_type mask_pos = mPos / UsedBitMaskWordBits;
439 size_type bit_pos = mPos % UsedBitMaskWordBits;
440 for (; mask_pos < UsedBitMaskWordCount; ++mask_pos)
441 {
442 const UsedBitMaskWord mask =
443 mKnownHeaders->mUsedBitMask[mask_pos] & static_cast<UsedBitMaskWord>(-(static_cast<UsedBitMaskWord>(1u) << bit_pos));
444 if (mask != 0u)
445 {
446 bit_pos = countrZeroNz(mask);
447 break;
448 }
449 bit_pos = 0u;
450 }
451
452 mPos = mask_pos * UsedBitMaskWordBits + bit_pos;
453
454 resip_assert(mPos < Headers::MAX_HEADERS || mPos == (static_cast<size_type>(UsedBitMaskWordCount) * UsedBitMaskWordBits));
455 }
456
457#if defined(_MSC_VER) && !defined(__clang__)
458#pragma warning(pop)
459#endif
460
468#if defined(__GNUC__) || defined(__clang__)
469 static unsigned int countrZeroNz(unsigned int bitmask) noexcept { return __builtin_ctz(bitmask); }
470 static unsigned int countrZeroNz(unsigned long bitmask) noexcept { return __builtin_ctzl(bitmask); }
471 static unsigned int countrZeroNz(unsigned long long bitmask) noexcept { return __builtin_ctzll(bitmask); }
472#elif defined(_MSC_VER)
473 static unsigned int countrZeroNz(uint32_t bitmask) noexcept
474 {
475 // On modern CPUs, tzcnt is slightly faster than bsf. CPUs without BMI1 will execute tzcnt
476 // and produce the same result as bsf for non-zero input.
477#if defined(_M_IX86) || defined(_M_X64)
478 return static_cast<unsigned int>(_tzcnt_u32(bitmask));
479#else
480 unsigned long res;
482 return static_cast<unsigned int>(res);
483#endif
484 }
485
486 static unsigned int countrZeroNz(uint64_t bitmask) noexcept
487 {
488#if defined(_M_X64)
489 return static_cast<unsigned int>(_tzcnt_u64(bitmask));
490#elif defined(_M_ARM64)
491 unsigned long res;
493 return static_cast<unsigned int>(res);
494#else
495 unsigned int base_count = 0u;
496 uint32_t bitmask32 = static_cast<uint32_t>(bitmask);
497 if (bitmask32 == 0u)
498 {
499 base_count = 32u;
500 bitmask32 = static_cast<uint32_t>(bitmask >> 32u);
501 }
502 return base_count + countrZeroNz(bitmask32);
503#endif
504 }
505#else
506 static unsigned int countrZeroNz(UsedBitMaskWord bitmask) noexcept
507 {
508 unsigned int res = 0u;
509 for (unsigned int bits = UsedBitMaskWordBits >> 1u; bits > 0u && (bitmask & 1u) == 0u; bits >>= 1u)
510 {
511 if ((bitmask & ((static_cast<UsedBitMaskWord>(1u) << bits) - 1u)) == 0u)
512 {
513 bitmask >>= bits;
514 res += bits;
515 }
516 }
517 return res;
518 }
519#endif
520 };
521
522 public:
523 using iterator = Iterator;
524 using const_iterator = Iterator;
525
526 private:
528 const KnownHeaders* mKnownHeaders;
529
530 private:
531 explicit OrderedView(KnownHeaders const& knownHeaders) noexcept : mKnownHeaders(&knownHeaders)
532 {
533 }
534
535 public:
537 bool empty() const noexcept { return mKnownHeaders->empty(); }
539 size_type size() const noexcept { return mKnownHeaders->size(); }
540
544
545 const_iterator begin() const noexcept { const_iterator it(mKnownHeaders, 0u); it.advanceToNextUsedEntry(); return it; }
546 const_iterator end() const noexcept { return const_iterator(mKnownHeaders, static_cast<size_type>(UsedBitMaskWordCount) * UsedBitMaskWordBits); }
547 };
548
550
551 private:
553 TypedHeaders mHeaders;
555 HeaderIndex mSize;
557 HeaderIndex mHeaderIndices[Headers::MAX_HEADERS];
559 UsedBitMaskWord mUsedBitMask[UsedBitMaskWordCount];
560
561 public:
562 KnownHeaders() noexcept : mSize(0u) { resetIndices(); }
564 noexcept(std::is_nothrow_constructible<TypedHeaders, const allocator_type&>::value) :
565 mHeaders(alloc),
566 mSize(0u)
567 {
568 resetIndices();
569 }
570
571 // Not copyable or moveable since the container elements may be associated with a memory pool
572 KnownHeaders(const KnownHeaders&) = delete;
574
576 bool empty() const noexcept { return mSize == 0u; }
578 size_type size() const noexcept { return static_cast<size_type>(mSize); }
580 void clear() noexcept;
589
593
594 const_iterator begin() const noexcept { const_iterator it(mHeaders.begin(), mHeaders.end()); it.advanceToNextUsedEntry(); return it; }
595 const_iterator end() const noexcept { return const_iterator(mHeaders.end(), mHeaders.end()); }
596
597 iterator begin() noexcept { iterator it(mHeaders.begin(), mHeaders.end()); it.advanceToNextUsedEntry(); return it; }
598 iterator end() noexcept { return iterator(mHeaders.end(), mHeaders.end()); }
599
601 void reserve(size_type capacity) { mHeaders.reserve(capacity); }
603 size_type capacity() const noexcept { return mHeaders.capacity(); }
604
606 iterator find(Headers::Type type) noexcept;
607 const_iterator find(Headers::Type type) const noexcept { return const_cast<KnownHeaders*>(this)->find(type); }
608
610 void erase(iterator it) noexcept;
611
621 template<typename ValuesFactory>
623
626
627 private:
629 void resetIndices() noexcept;
630 };
631
634 SipMessage(const SipMessage& message);
635
638
640
643
652
654
662 static SipMessage* make(const Data& buffer, bool isExternal = false);
663 void parseAllHeaders();
664
666
671 {
672 public:
677 Exception(const Data& msg, const Data& file, const int line)
678 : BaseException(msg, file, line) {}
683 const char* name() const noexcept override { return "SipMessage::Exception"; }
684 };
685
687 inline void setFromTU() { mIsExternal = false; }
688
690 inline void setFromExternal() { mIsExternal = true; }
691
699 inline bool isExternal() const { return mIsExternal; }
700
711 inline bool isFromWire() const { return mReceivedTransportTuple.getType() != UNKNOWN_TRANSPORT; }
712
716 virtual bool isClientTransaction() const;
717
722 virtual EncodeStream& encode(EncodeStream& str) const;
723 //sipfrags will not output Content Length if there is no body--introduce
724 //friendship to hide this?
727
728 virtual EncodeStream& encodeBrief(EncodeStream& str) const;
730
732 inline bool isRequest() const {return mRequest;}
734 inline bool isResponse() const {return mResponse;}
736 inline bool isInvalid() const {return mInvalid;}
737
742 const Data& methodStr() const;
743
745 const resip::Data* getReason() const { return mReason; }
746
748 const RequestLine& header(const RequestLineType& l) const;
749
752
753 inline const RequestLine& const_header(const RequestLineType& l) const { return header(l); }
754
756 const StatusLine& header(const StatusLineType& l) const;
757
760
761 inline const StatusLine& const_header(const StatusLineType& l) const { return header(l); }
762
764 bool exists(const HeaderBase& headerType) const;
766 bool empty(const HeaderBase& headerType) const;
770 inline void remove(const HeaderBase& headerType) { remove(headerType.getTypeNum()); }
771
772 void remove(Headers::Type type);
773
774#define defineHeader(_header, _name, _type, _rfc) \
775 const H_##_header::Type& header(const H_##_header& headerType) const; \
776 H_##_header::Type& header(const H_##_header& headerType); \
777 inline const H_##_header::Type& const_header(const H_##_header& headerType) const \
778 {\
779 return header(headerType);\
780 }
781
782
783#define defineMultiHeader(_header, _name, _type, _rfc) \
784 const H_##_header##s::Type& header(const H_##_header##s& headerType) const; \
785 H_##_header##s::Type& header(const H_##_header##s& headerType); \
786 inline const H_##_header##s::Type& const_header(const H_##_header##s& headerType) const \
787 {\
788 return header(headerType);\
789 }
790
791 defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261");
792 defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261");
793 defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261");
794 defineHeader(Priority, "Priority", Token, "RFC 3261");
795 defineHeader(Event, "Event", Token, "RFC 3265");
796 defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265");
797 defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903");
798 defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903");
799 defineHeader(ContentId, "Content-ID", Token, "RFC 2045");
800 defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265");
801 defineMultiHeader(Identity, "Identity", IdentityCategory, "RFC 8224"); // Originally defined in RFC 4474 as a single header, but later modified by RFC8224 to be a multiheader
802 defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261");
803 defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261");
804 defineMultiHeader(Allow, "Allow", Token, "RFC 3261");
805 defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261");
806 defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261");
807 defineMultiHeader(Require, "Require", Token, "RFC 3261");
808 defineMultiHeader(Supported, "Supported", Token, "RFC 3261");
809 defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261");
810 defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329");
811 defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329");
812 defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329");
813 defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841");
814 defineMultiHeader(Reason, "Reason", Token, "RFC 3326");
815 defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323");
816 defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313");
817 defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488");
818 defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-04");
819 defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-04");
820
821 defineMultiHeader(Accept, "Accept", Mime, "RFC 3261");
822 defineHeader(ContentType, "Content-Type", Mime, "RFC 3261");
823
824 defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261");
825 defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261");
826 defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261");
827 defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474");
828
829 defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261");
830 defineMultiHeader(Route, "Route", NameAddr, "RFC 3261");
831 defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261");
832 defineHeader(From, "From", NameAddr, "RFC 3261");
833 defineHeader(To, "To", NameAddr, "RFC 3261");
834 defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261");
835 defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515");
836 defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892");
837 defineMultiHeader(Path, "Path", NameAddr, "RFC 3327");
838 defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841");
839 defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841");
840 defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325");
841 defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325");
842 defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455");
843 defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455");
844 defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608");
845 defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep?
846 defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244");
847 defineMultiHeader(Diversion, "Diversion", NameAddr, "RFC 5806");
848
849 defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC 1521");
850 defineHeader(Organization, "Organization", StringCategory, "RFC 3261");
851 defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455");
852 defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76");
853 defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76");
854 defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76");
855 defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76");
856 defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455");
857 defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265");
858 defineHeader(Server, "Server", StringCategory, "RFC 3261");
859 defineHeader(Subject, "Subject", StringCategory, "RFC 3261");
860 defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261");
861 defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261");
862
863 defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261");
864 defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261");
865 defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261");
866 defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261");
867
869 defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261");
870 defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626");
871
872 defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261");
873 defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028");
874 defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028");
875
876 defineHeader(CallID, "Call-ID", CallID, "RFC 3261");
877 defineHeader(Replaces, "Replaces", CallID, "RFC 3891");
878 defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261");
879 defineHeader(Join, "Join", CallId, "RFC 3911");
880 defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538");
881
882 defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261");
883 defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261");
884 defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261");
885 defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261");
886 defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261");
887
888 defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261");
889 defineHeader(Date, "Date", DateCategory, "RFC 3261");
890 defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261");
891 defineMultiHeader(Via, "Via", Via, "RFC 3261");
892 defineHeader(RAck, "RAck", RAckCategory, "RFC 3262");
893
894 defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"); // section 5.4.
895 defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455");
896 defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455");
898
899 defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17");
900
902
907 const StringCategories& header(const ExtensionHeader& symbol) const;
908
915 bool exists(const ExtensionHeader& symbol) const;
916 void remove(const ExtensionHeader& symbol);
917
921 const KnownHeaders& getRawHeaders() const noexcept { return mKnownHeaders; }
922 const UnknownHeaders& getRawUnknownHeaders() const noexcept { return mUnknownHeaders; }
923
931 const HeaderFieldValue& getRawBody() const noexcept { return mContentsHfv; }
932
941 void setRawBody(const HeaderFieldValue& body);
942
951 Contents* getContents() const;
952
954 std::unique_ptr<Contents> releaseContents();
955
958 void setContents(const Contents* contents);
959 void setContents(std::unique_ptr<Contents> contents);
960
962 void setStartLine(const char* start, uint32_t len);
963
964 void setBody(const char* start, uint32_t len);
965
968 const char* headerName, uint32_t headerNameLen,
969 const char* value, uint32_t valuelen);
970
971 // Returns the source tuple for the transport that the message was received from
972 // only makes sense for messages received from the wire. Differs from Source
973 // since it contains the transport bind address instead of the actual source
974 // address.
975 const Tuple& getReceivedTransportTuple() const { return mReceivedTransportTuple; }
976
978 void setReceivedTransportTuple(const Tuple& transportTuple) { mReceivedTransportTuple = transportTuple;}
979
980 // Returns the source tuple that the message was received from
981 // only makes sense for messages received from the wire
982 void setSource(const Tuple& tuple) { mSource = tuple; }
985 const Tuple& getSource() const { return mSource; }
986
988 void setDestination(const Tuple& tuple) { mDestination = tuple; }
989 Tuple& getDestination() { return mDestination; }
990
991 void addBuffer(char* buf);
992
993 uint64_t getCreatedTimeMicroSec() const { return mCreatedTime; }
994
996 void setForceTarget(const Uri& uri);
997 void clearForceTarget();
998 const Uri& getForceTarget() const;
999 bool hasForceTarget() const;
1000
1001 const Data& getTlsDomain() const { return mTlsDomain; }
1002 void setTlsDomain(const Data& domain) { mTlsDomain = domain; }
1003
1007 const std::shared_ptr<const ConnectionInfo>& getConnectionInfo() const noexcept { return mConnectionInfo; }
1008 void setConnectionInfo(std::shared_ptr<const ConnectionInfo> connectionInfo) noexcept { mConnectionInfo = std::move(connectionInfo); }
1009
1010 // Shortcuts to the fields of getConnectionInfo(); empty if there is none.
1011 const std::list<Data>& getTlsPeerNames() const;
1015 const Data& getTlsSni() const;
1016 const CookieList& getWsCookies() const;
1017 std::shared_ptr<WsCookieContext> getWsCookieContext() const noexcept;
1018
1019 // Each of these gives this message its own copy of the ConnectionInfo with
1020 // the one field changed, so other messages from the same connection keep
1021 // theirs.
1024 void setWsCookieContext(std::shared_ptr<WsCookieContext> wsCookieContext);
1025
1027
1029
1030 void setSecurityAttributes(std::unique_ptr<SecurityAttributes>) noexcept;
1031 const SecurityAttributes* getSecurityAttributes() const noexcept { return mSecurityAttributes.get(); }
1032
1035 void addOutboundDecorator(std::unique_ptr<MessageDecorator> md){mOutboundDecorators.push_back(md.release());}
1037 void callOutboundDecorators(const Tuple &src,
1038 const Tuple &dest,
1039 const Data& sigcompId);
1044
1046
1047 protected:
1048 // !bwc! Removes or zeros all pointers to heap-allocated memory this
1049 // class owns.
1050 void clear(bool leaveResponseStuff=false);
1051 // !bwc! Frees all heap-allocated memory owned.
1052 void freeMem(bool leaveResponseStuff=false);
1053 // Clears mHeaders and cleans up memory
1054 void clearHeaders();
1055
1056 // !bwc! Initializes members. Will not free heap-allocated memory.
1057 // Will begin by calling clear().
1058 void init(const SipMessage& rhs);
1059
1060 private:
1061 void compute2543TransactionHash() const;
1062
1063 EncodeStream&
1064 encode(EncodeStream& str, bool isSipFrag) const;
1065
1066 void copyFrom(const SipMessage& message);
1067
1068 HeaderFieldValueList* ensureHeaders(Headers::Type type);
1069 HeaderFieldValueList* ensureHeaders(Headers::Type type) const; // throws if not present
1070
1071 HeaderFieldValueList* ensureHeader(Headers::Type type);
1072 HeaderFieldValueList* ensureHeader(Headers::Type type) const; // throws if not present
1073
1074 void throwHeaderMissing(Headers::Type type) const;
1075
1076 inline HeaderFieldValueList* getEmptyHfvl()
1077 {
1078 void* ptr(mPool.allocate(sizeof(HeaderFieldValueList)));
1079 return new (ptr) HeaderFieldValueList(mPool);
1080 }
1081
1082 inline HeaderFieldValueList* getCopyHfvl(const HeaderFieldValueList& hfvl)
1083 {
1084 void* ptr(mPool.allocate(sizeof(HeaderFieldValueList)));
1085 return new (ptr) HeaderFieldValueList(hfvl, mPool);
1086 }
1087
1088 inline void freeHfvl(HeaderFieldValueList* hfvl)
1089 {
1090 if(hfvl)
1091 {
1093 mPool.deallocate(hfvl);
1094 }
1095 }
1096
1097 template<class T>
1098 ParserContainer<T>* makeParserContainer()
1099 {
1100 void* ptr(mPool.allocate(sizeof(ParserContainer<T>)));
1101 return new (ptr) ParserContainer<T>(mPool);
1102 }
1103
1104 template<class T>
1105 ParserContainer<T>* makeParserContainer(HeaderFieldValueList* hfvs,
1107 {
1108 void* ptr(mPool.allocate(sizeof(ParserContainer<T>)));
1109 return new (ptr) ParserContainer<T>(hfvs, type, mPool);
1110 }
1111
1112 // indicates this message came from the wire or we want it to look like it
1113 // came from the wire (ie. internally generated responses to an internally
1114 // generated request), set by the Transport and setFromTu and setFromExternal APIs
1115 bool mIsExternal;
1116
1117 // Sizing so that average SipMessages don't need to allocate heap memory
1118 // To profile current sizing, enable DINKYPOOL_PROFILING in SipMessage.cxx
1119 // and look for DebugLog message in SipMessage destructor to know when heap
1120 // allocations are occuring and how much of the pool is used.
1121 DinkyPool<3732> mPool;
1122
1123 // raw text corresponding to each typed header (not yet parsed)
1124 KnownHeaders mKnownHeaders;
1125
1126 // raw text corresponding to each unknown header
1127 UnknownHeaders mUnknownHeaders;
1128
1129 // For messages received from the wire, this indicates information about
1130 // the transport the message was received on
1131 Tuple mReceivedTransportTuple;
1132
1133 // For messages received from the wire, this indicates where it came
1134 // from. Can be used to get to the Transport and/or reliable Connection
1135 Tuple mSource;
1136
1137 // Used by the TU to specify where a message is to go
1138 Tuple mDestination;
1139
1140 // Raw buffers coming from the Transport. message manages the memory
1141 std::vector<char*> mBufferList;
1142
1143 // special case for the first line of message
1144 StartLine* mStartLine;
1145 char mStartLineMem[sizeof(RequestLine) > sizeof(StatusLine) ? sizeof(RequestLine) : sizeof(StatusLine)];
1146
1147 // raw text for the contents (all of them)
1148 HeaderFieldValue mContentsHfv;
1149
1150 // lazy parser for the contents
1151 mutable Contents* mContents;
1152
1153 // cached value of a hash of the transaction id for a message received
1154 // from a 2543 sip element. as per rfc3261 see 17.2.3
1155 mutable Data mRFC2543TransactionId;
1156
1157 // is a request or response
1158 bool mRequest;
1159 bool mResponse;
1160
1161 bool mInvalid;
1162 resip::Data* mReason;
1163
1164 uint64_t mCreatedTime;
1165
1166 // used when next element is a strict router OR
1167 // client forces next hop OOB
1168 Uri* mForceTarget;
1169
1170 // domain associated with this message for tls cert
1171 Data mTlsDomain;
1172
1173 // TLS peer names, SNI and WebSocket cookies of the connection the message
1174 // was received on, shared with every other message from that connection
1175 std::shared_ptr<const ConnectionInfo> mConnectionInfo;
1176
1177 std::unique_ptr<SecurityAttributes> mSecurityAttributes;
1178
1179 std::vector<MessageDecorator*> mOutboundDecorators;
1180
1181 friend class TransportSelector;
1182};
1183
1184}
1185
1186#undef ensureHeaderTypeUseable
1187#undef ensureSingleHeader
1188#undef ensureMultiHeader
1189#undef defineHeader
1190#undef defineMultiHeader
1191
1192#endif
1193
1194/* ====================================================================
1195 * The Vovida Software License, Version 1.0
1196 *
1197 * Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
1198 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
1199 *
1200 * Redistribution and use in source and binary forms, with or without
1201 * modification, are permitted provided that the following conditions
1202 * are met:
1203 *
1204 * 1. Redistributions of source code must retain the above copyright
1205 * notice, this list of conditions and the following disclaimer.
1206 *
1207 * 2. Redistributions in binary form must reproduce the above copyright
1208 * notice, this list of conditions and the following disclaimer in
1209 * the documentation and/or other materials provided with the
1210 * distribution.
1211 *
1212 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1213 * and "Vovida Open Communication Application Library (VOCAL)" must
1214 * not be used to endorse or promote products derived from this
1215 * software without prior written permission. For written
1216 * permission, please contact vocal@vovida.org.
1217 *
1218 * 4. Products derived from this software may not be called "VOCAL", nor
1219 * may "VOCAL" appear in their name, without prior written
1220 * permission of Vovida Networks, Inc.
1221 *
1222 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1223 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1224 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1225 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
1226 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1227 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1228 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1229 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1230 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1231 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1232 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1233 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1234 * DAMAGE.
1235 *
1236 * ====================================================================
1237 *
1238 * This software consists of voluntary contributions made by Vovida
1239 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1240 * Inc. For more information on Vovida Networks, Inc., please see
1241 * <http://www.vovida.org/>.
1242 *
1243 * vi: set shiftwidth=3 expandtab:
1244 */
Data bits(size_t v)
Definition Data.cxx:2342
#define resip_assert(x)
This file needs to work for both C and C++ code.
Represents the "credentials" and "challenge" elements in the SIP grammar.
Definition Auth.hxx:18
The abstract base-class for all exceptions thrown by resip code.
Represents a CSeq header field value (this doesn't have an official name in the RFC 3261 grammar).
Represents the "callid" element in the SIP grammar.
Definition CallId.hxx:18
Base class for all SIP body types.
Definition Contents.hxx:51
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
Represents the "SIP-date" element in the RFC 3261 grammar.
Represents the header field value for an Expires-type header.
Represents the "absoluteURI" element in the RFC 3261 grammar.
Maps from header name to derived ParserCategory.
Represents an Identity header from RFC8824.
The base-class used for message-passing.
Definition Message.hxx:21
Represents the "media-type" element in the RFC 3261 grammar.
Definition Mime.hxx:20
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
Definition NameAddr.hxx:19
Represents the "token" element in the RFC 3261 grammar.
Represents the RAck header field value defined in the RFC 3262 grammar.
Represents the "Request-Line" element in the RFC 3261 grammar.
Base exception for SipMessage related exceptions.
const char * name() const noexcept override
returns the class name of the exception instance
Exception(const Data &msg, const Data &file, const int line)
constructor that records an exception message, the file and the line that the exception occured in.
Publicly accessible information about a header.
HeaderFieldValueList * getValues() const noexcept
Returns header values.
void setValues(HeaderFieldValueList *values) noexcept
Sets header values.
constexpr HeaderInfo(Headers::Type type, HeaderFieldValueList *values=nullptr) noexcept
Headers::Type getType() const noexcept
Returns header type.
Ordered view over headers. The headers are produced in the order of Headers::Type enum values.
KnownHeaders::difference_type difference_type
const_iterator cend() const noexcept
const_iterator begin() const noexcept
size_type size() const noexcept
Returns the number of elements in the container. Does not consider "unused" elements.
const_iterator end() const noexcept
KnownHeaders::const_reference const_reference
KnownHeaders::const_pointer const_pointer
const_iterator cbegin() const noexcept
Iterator access.
bool empty() const noexcept
Returns true if the container is empty. Does not consider "unused" elements.
List of known SIP headers, searchable by header type.
friend class OrderedView::Iterator
const_iterator find(Headers::Type type) const noexcept
TypedHeaders::difference_type difference_type
const_iterator cbegin() const noexcept
Iterator access.
void reserve(size_type capacity)
Reserves internal storage for the given number of entries.
TypedHeaders::pointer pointer
const_iterator begin() const noexcept
iterator insert(Headers::Type type, ValuesFactory &&valuesFactory)
Constructs or reuses a previously erased element for a given header type.
OrderedView ordered() const noexcept
Returns an ordered view over the list of headers.
UsedIterator< TypedHeaders::iterator > iterator
TypedHeaders::const_reference const_reference
TypedHeaders::allocator_type allocator_type
KnownHeaders(const allocator_type &alloc) noexcept(std::is_nothrow_constructible< TypedHeaders, const allocator_type & >::value)
iterator find(Headers::Type type) noexcept
Finds header information, if present in the list. Returns end() if not found. Does not produce "unuse...
void clearAndDispose(Disposer &&disposer) noexcept
Clears the container and invokes the dispose function on every element.
bool empty() const noexcept
Returns true if the container is empty. Does not consider "unused" elements.
TypedHeaders::const_pointer const_pointer
UsedIterator< TypedHeaders::const_iterator > const_iterator
TypedHeaders::value_type value_type
TypedHeaders::reference reference
KnownHeaders & operator=(const KnownHeaders &)=delete
TypedHeaders::size_type size_type
size_type size() const noexcept
Returns the number of elements in the container. Does not consider "unused" elements.
size_type capacity() const noexcept
Returns capacity of the internal storage.
void erase(iterator it) noexcept
Erases an element. Does not free the HeaderFieldValueList object but clears it and marks as "unused".
KnownHeaders(const KnownHeaders &)=delete
void clear() noexcept
Clears the container. Does not free HeaderFieldValueList objects but clears them and marks as "unused...
const_iterator cend() const noexcept
const_iterator end() const noexcept
Represents a SIP message.
void addBuffer(char *buf)
defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261")
defineMultiHeader(Route, "Route", NameAddr, "RFC 3261")
defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261")
defineMultiHeader(Accept, "Accept", Mime, "RFC 3261")
defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261")
const KnownHeaders & getRawHeaders() const noexcept
defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-04")
defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261")
defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244")
std::unique_ptr< Contents > releaseContents()
Removes the contents from the message.
defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-04")
void copyOutboundDecoratorsToStackFailureAck(SipMessage &ack)
defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323")
Tuple & getDestination()
const std::list< Data > & getTlsPeerNames() const
defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329")
defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325")
std::list< std::pair< Data, HeaderFieldValueList * >, StlPoolAllocator< std::pair< Data, HeaderFieldValueList * >, PoolBase > > UnknownHeaders
void setDestination(const Tuple &tuple)
Used by the stateless interface to specify where to send a request/response.
defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261")
void setRFC2543TransactionId(const Data &tid)
void setContents(const Contents *contents)
Set the contents of the message.
void setStartLine(const char *start, uint32_t len)
static SipMessage * make(const Data &buffer, bool isExternal=false)
Construct a SipMessage object from a string containing a SIP request or response.
bool isRequest() const
Returns true if message is a request, false otherwise.
const Data & getRFC2543TransactionId() const
Calculates an MD5 hash over the Request-URI, To tag (for non-INVITE transactions),...
void setWsCookies(const CookieList &wsCookies)
bool hasForceTarget() const
defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261")
SipMessage & mergeUri(const Uri &source)
defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76")
defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515")
virtual bool isClientTransaction() const
Check if SipMessage is a client transaction.
void setWsCookieContext(std::shared_ptr< WsCookieContext > wsCookieContext)
defineMultiHeader(Diversion, "Diversion", NameAddr, "RFC 5806")
defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261")
const Data & methodStr() const
Returns a string containing the SIP method for the message.
defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261")
Contents * getContents() const
Retrieves the body of a SIP message.
defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261")
void setConnectionInfo(std::shared_ptr< const ConnectionInfo > connectionInfo) noexcept
defineHeader(To, "To", NameAddr, "RFC 3261")
defineMultiHeader(Via, "Via", Via, "RFC 3261")
void setBody(const char *start, uint32_t len)
void callOutboundDecorators(const Tuple &src, const Tuple &dest, const Data &sigcompId)
void setRawHeader(const HeaderFieldValueList *hfvs, Headers::Type headerType)
defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261")
defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538")
defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455")
void setTlsDomain(const Data &domain)
const Data & getTlsSni() const
SNI (TLS server_name) the peer sent in its ClientHello.
void freeMem(bool leaveResponseStuff=false)
defineHeader(ContentId, "Content-ID", Token, "RFC 2045")
defineMultiHeader(Supported, "Supported", Token, "RFC 3261")
defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261")
defineHeader(ContentType, "Content-Type", Mime, "RFC 3261")
const Tuple & getReceivedTransportTuple() const
defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261")
defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841")
const UnknownHeaders & getRawUnknownHeaders() const noexcept
defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261")
void addOutboundDecorator(std::unique_ptr< MessageDecorator > md)
Call a MessageDecorator to process the message before it is sent to the transport.
defineHeader(Priority, "Priority", Token, "RFC 3261")
void setSecurityAttributes(std::unique_ptr< SecurityAttributes >) noexcept
defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325")
defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261")
defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261")
defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265")
void init(const SipMessage &rhs)
defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261")
void setForceTarget(const Uri &uri)
deal with a notion of an "out-of-band" forced target for SIP routing
defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261")
defineMultiHeader(Identity, "Identity", IdentityCategory, "RFC 8224")
defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76")
defineHeader(Server, "Server", StringCategory, "RFC 3261")
defineHeader(RAck, "RAck", RAckCategory, "RFC 3262")
defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455")
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903")
defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313")
defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261")
virtual const Data & getTransactionId() const
Returns the transaction id from the branch or if 2543, the computed hash.
defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261")
void addHeader(Headers::Type header, const char *headerName, uint32_t headerNameLen, const char *value, uint32_t valuelen)
Add HeaderFieldValue given enum, header name and value.
defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261")
defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903")
defineHeader(Replaces, "Replaces", CallID, "RFC 3891")
defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455")
EncodeStream & encodeEmbedded(EncodeStream &str) const
defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17")
defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261")
defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261")
defineHeader(Organization, "Organization", StringCategory, "RFC 3261")
defineMultiHeader(Path, "Path", NameAddr, "RFC 3327")
bool isResponse() const
Returns true if message is a response, false otherwise.
const RequestLine & const_header(const RequestLineType &l) const
defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329")
defineMultiHeader(Allow, "Allow", Token, "RFC 3261")
void setRawBody(const HeaderFieldValue &body)
Remove any existing body/contents, and (if non-empty) set the body to {body}.
defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626")
const resip::Data * getReason() const
Returns a string containing the response reason text.
const Uri & getForceTarget() const
EncodeStream & encodeSingleHeader(Headers::Type type, EncodeStream &str) const
void setFromExternal()
Mark message as externally generated.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
virtual EncodeStream & encodeSipFrag(EncodeStream &str) const
const Tuple & getSource() const
Returns the source tuple that the message was received from only makes sense for messages received fr...
defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261")
defineHeader(Event, "Event", Token, "RFC 3265")
defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841")
static bool checkContentLength
bool isFromWire() const
Check if SipMessage came off the wire.
void remove(const HeaderBase &headerType)
Prevents a header field from being present when the message is prepared for sending to a transport.
virtual Message * clone() const
defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028")
const HeaderFieldValue & getRawBody() const noexcept
Return the raw body string (if it exists).
defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261")
defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608")
defineHeader(Subject, "Subject", StringCategory, "RFC 3261")
virtual EncodeStream & encodeBrief(EncodeStream &str) const
output a brief description to stream
defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261")
defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474")
defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76")
defineHeader(CallID, "Call-ID", CallID, "RFC 3261")
defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04")
const std::shared_ptr< const ConnectionInfo > & getConnectionInfo() const noexcept
TLS and WebSocket details of the connection this message was received on, shared by every message rec...
void setReceivedTransportTuple(const Tuple &transportTuple)
Set Tuple for transport from whence this message came.
defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261")
defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841")
defineHeader(Join, "Join", CallId, "RFC 3911")
void copyOutboundDecoratorsToStackCancel(SipMessage &cancel)
defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455")
const SecurityAttributes * getSecurityAttributes() const noexcept
defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76")
defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329")
defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261")
void rollbackOutboundDecorators()
defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455")
const Data & getTlsDomain() const
const StatusLine & const_header(const StatusLineType &l) const
defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261")
defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265")
defineMultiHeader(Reason, "Reason", Token, "RFC 3326")
uint64_t getCreatedTimeMicroSec() const
const CookieList & getWsCookies() const
defineHeader(Date, "Date", DateCategory, "RFC 3261")
defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265")
bool isExternal() const
Check if SipMessage is to be treated as it came off the wire.
bool isInvalid() const
Returns true if message failed to parse, false otherwise.
void setSource(const Tuple &tuple)
void clearOutboundDecorators()
defineMultiHeader(Require, "Require", Token, "RFC 3261")
defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC 1521")
defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261")
std::shared_ptr< WsCookieContext > getWsCookieContext() const noexcept
defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028")
void setTlsPeerNames(const std::list< Data > &tlsPeerNames)
const HeaderFieldValueList * getRawHeader(Headers::Type headerType) const
typeless header interface
defineHeader(From, "From", NameAddr, "RFC 3261")
resip::MethodTypes method() const
returns the method type of the message
Data getCanonicalIdentityString() const
defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455")
RESIP_HeapCount(SipMessage)
void setFromTU()
Mark message as internally generated.
defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315")
virtual EncodeStream & encode(EncodeStream &str) const
Generate a string from the SipMessage object.
defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455")
defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892")
defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261")
defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488")
Represents the "Status-Line" element in the RFC 3261 grammar.
A dirt-simple lightweight stl pool allocator meant for use in short-lifetime objects.
Represents the "header-value" element in the RFC 3261 grammar (ie, an unknown header field value).
Generically represents a token whose value can be wrapped and encoded using double quotes.
Represents the "token" element in the RFC 3261 grammar.
Definition Token.hxx:18
Represents a network address.
Definition Tuple.hxx:59
Represents a numeric-with-comment header field value.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
Represents the "via-parm" element in the RFC 3261 grammar.
Definition Via.hxx:18
Represents the "warning-value" element in the RFC 3261 grammar.
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
dcm! – add UnusedChecking(_enum) below;
unsigned long long uint64_t
Definition Stun.hxx:39
unsigned int uint32_t
Definition Stun.hxx:34
@ UNKNOWN_TRANSPORT
ParserContainer< StringCategory > StringCategories
Definition Headers.hxx:213
bool operator==(const char *lhs, const Data &rhs)
Definition Data.hxx:1197
bool operator!=(const Data &lhs, const Data &rhs)
Definition Data.hxx:1187
std::vector< Cookie > CookieList
Definition Cookie.hxx:35
#define EncodeStream
unsigned __int64 uint64_t
Definition stdint.h:95
void list()
Definition userAdmin.cxx:66