/src/resiprocate/resip/stack/SipMessage.hxx
Line | Count | Source |
1 | | #if !defined(RESIP_SIPMESSAGE_HXX) |
2 | | #define RESIP_SIPMESSAGE_HXX |
3 | | |
4 | | #include <sys/types.h> |
5 | | |
6 | | #include <list> |
7 | | #include <vector> |
8 | | #include <utility> |
9 | | #include <memory> |
10 | | |
11 | | #include "resip/stack/Contents.hxx" |
12 | | #include "resip/stack/Headers.hxx" |
13 | | #include "resip/stack/TransactionMessage.hxx" |
14 | | #include "resip/stack/ParserContainer.hxx" |
15 | | #include "resip/stack/ParserCategories.hxx" |
16 | | #include "resip/stack/SecurityAttributes.hxx" |
17 | | #include "resip/stack/Tuple.hxx" |
18 | | #include "resip/stack/Uri.hxx" |
19 | | #include "resip/stack/MessageDecorator.hxx" |
20 | | #include "resip/stack/Cookie.hxx" |
21 | | #include "resip/stack/WsCookieContext.hxx" |
22 | | #include "rutil/BaseException.hxx" |
23 | | #include "rutil/Data.hxx" |
24 | | #include "rutil/DinkyPool.hxx" |
25 | | #include "rutil/StlPoolAllocator.hxx" |
26 | | #include "rutil/Timer.hxx" |
27 | | #include "rutil/HeapInstanceCounter.hxx" |
28 | | |
29 | | namespace resip |
30 | | { |
31 | | |
32 | | class Contents; |
33 | | class ExtensionHeader; |
34 | | class SecurityAttributes; |
35 | | |
36 | | /** |
37 | | @ingroup resip_crit |
38 | | @ingroup message_passing_tu |
39 | | @brief Represents a SIP message. |
40 | | |
41 | | This is the class that your app will spend the most time working with. This |
42 | | is because, in the UA core/Transaction User architecture, the vast majority |
43 | | of interaction is carried out through SIP messaging. |
44 | | |
45 | | When you get a SipMessage, generally the first thing you want to know is |
46 | | whether it is a request or a response. This is done by calling |
47 | | SipMessage::isRequest() or SipMessage::isResponse(). |
48 | | |
49 | | Next, it is usually important to determine what the SIP method of the message |
50 | | is. This is done by calling SipMessage::method() (this is a convenience |
51 | | function that checks the method of the Request-Line if the message is a |
52 | | request, or the method of the CSeq if a response). |
53 | | |
54 | | At this point, it may become useful to examine the start-line of the message. |
55 | | |
56 | | If the message is a request, you can get the Request-Line (represented by a |
57 | | RequestLine&) by calling SipMessage::header(const RequestLineType&) |
58 | | @code |
59 | | RequestLine& rLine = sip.header(h_RequestLine); |
60 | | @endcode |
61 | | |
62 | | If the message is a response, you can get the Status-Line (represented by a StatusLine&) by calling SipMessage::header(const StatusLineType&) |
63 | | @code |
64 | | StatusLine& sLine = sip.header(h_StatusLine); |
65 | | @endcode |
66 | | |
67 | | From here, examination of the various headers is in order. The way the |
68 | | underlying code works is very complicated, but fortunately relatively |
69 | | painless to use. For each header type, there is a subclass of HeaderBase, and |
70 | | a SipMessage::header() function that takes a reference to this subclass. On |
71 | | top of this, there is a static instance of each of these subclasses. Examples |
72 | | include h_To, h_From, h_CSeq, h_CallId, h_Routes, h_Contacts, h_RecordRoutes, |
73 | | etc. |
74 | | |
75 | | @code |
76 | | NameAddr& to = sip.header(h_To); |
77 | | NameAddr& from = sip.header(h_From); |
78 | | CSeqCategory& cseq = sip.header(h_CSeq); |
79 | | CallId& callId = sip.header(h_CallId); |
80 | | ParserContainer<NameAddr>& routes = sip.header(h_Routes); |
81 | | ParserContainer<NameAddr>& contacts = sip.header(h_Contacts); |
82 | | ParserContainer<NameAddr>& rRoutes = sip.header(h_RecordRoutes); |
83 | | @endcode |
84 | | |
85 | | Generally speaking, the access token is named in a predictable fashion; all |
86 | | non-alphanumeric characters are omitted, the first letter of each word is |
87 | | capitalized, and the name is pluralized if the header is multi-valued (since |
88 | | this stuff is all macro-generated, sometimes this pluralization isn't quite |
89 | | right; h_AllowEventss, h_PAssertedIdentitys). |
90 | | |
91 | | When accessing a single-value header, you need to check whether it |
92 | | exists first (unless you want it to be created implicitly). Also, since all |
93 | | header field values are lazily parsed (see LazyParser), you'll want to make |
94 | | sure it is well-formed before attempting to access any portion of it. |
95 | | |
96 | | @code |
97 | | if(sip.exists(h_Event)) |
98 | | { |
99 | | Token& event = sip.header(h_Event); |
100 | | if(event.isWellFormed()) |
101 | | { |
102 | | // do stuff with event. |
103 | | } |
104 | | else |
105 | | { |
106 | | // complain bitterly |
107 | | } |
108 | | } |
109 | | @endcode |
110 | | |
111 | | When accessing a multi-value header, it is important to keep in mind that |
112 | | it can be empty, even if it exists (for example, "Supported: " has a meaning |
113 | | that is distinct from the lack of a Supported header). |
114 | | |
115 | | @code |
116 | | if(sip.exists(h_Contacts)) |
117 | | { |
118 | | ParserContainer<NameAddr>& contacts = sip.header(h_Contacts); |
119 | | if(!contacts.empty()) |
120 | | { |
121 | | NameAddr& frontContact = contacts.front(); |
122 | | if(frontContact.isWellFormed()) |
123 | | { |
124 | | // do stuff with frontContact |
125 | | } |
126 | | else |
127 | | { |
128 | | // complain bitterly |
129 | | } |
130 | | } |
131 | | else |
132 | | { |
133 | | // complain bitterly |
134 | | } |
135 | | } |
136 | | @endcode |
137 | | |
138 | | In some cases, you will need to access header-types that are not natively |
139 | | supported by the stack (ie, don't have an access-token). ExtensionHeader will |
140 | | allow you to construct an access-token at runtime that will retrieve the |
141 | | header field value as a ParserContainer<StringCategory>. Here's an example: |
142 | | |
143 | | @code |
144 | | // We need to access the FooBar header field value here. |
145 | | static ExtensionHeader h_FooBar("FooBar"); |
146 | | if(sip.exists(h_FooBar)) |
147 | | { |
148 | | ParserContainer<StringCategory>& fooBars = sip.header(h_FooBar); |
149 | | } |
150 | | @endcode |
151 | | |
152 | | */ |
153 | | class SipMessage : public TransactionMessage |
154 | | { |
155 | | public: |
156 | | RESIP_HeapCount(SipMessage); |
157 | | #ifndef __SUNPRO_CC |
158 | | typedef std::list< std::pair<Data, HeaderFieldValueList*>, StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase > > UnknownHeaders; |
159 | | #else |
160 | | typedef std::list< std::pair<Data, HeaderFieldValueList*> > UnknownHeaders; |
161 | | #endif |
162 | | |
163 | | explicit SipMessage(const Tuple *receivedTransport = 0); |
164 | | /// @todo .dlb. public, allows pass by value to compile. |
165 | | SipMessage(const SipMessage& message); |
166 | | |
167 | | /// @todo .dlb. sure would be nice to have overloaded return value here.. |
168 | | virtual Message* clone() const; |
169 | | |
170 | | SipMessage& operator=(const SipMessage& rhs); |
171 | | |
172 | | /// Returns the transaction id from the branch or if 2543, the computed hash. |
173 | | virtual const Data& getTransactionId() const; |
174 | | |
175 | | /** |
176 | | @brief Calculates an MD5 hash over the Request-URI, To tag (for |
177 | | non-INVITE transactions), From tag, Call-ID, CSeq (including |
178 | | the method), and top Via header. The hash is used for |
179 | | transaction matching. |
180 | | */ |
181 | | const Data& getRFC2543TransactionId() const; |
182 | | void setRFC2543TransactionId(const Data& tid); |
183 | | |
184 | | virtual ~SipMessage(); |
185 | | |
186 | | /** @brief Construct a SipMessage object from a string containing a SIP request |
187 | | or response. |
188 | | |
189 | | @param buffer a buffer containing a SIP message |
190 | | @param isExternal true for a message generated externally, false otherwise. |
191 | | @return constructed SipMessage object |
192 | | */ |
193 | | static SipMessage* make(const Data& buffer, bool isExternal = false); |
194 | | void parseAllHeaders(); |
195 | | |
196 | | static bool checkContentLength; |
197 | | |
198 | | /** |
199 | | @brief Base exception for SipMessage related exceptions |
200 | | */ |
201 | | class Exception final : public BaseException |
202 | | { |
203 | | public: |
204 | | /** |
205 | | @brief constructor that records an exception message, the file and the line |
206 | | that the exception occured in. |
207 | | */ |
208 | | Exception(const Data& msg, const Data& file, const int line) |
209 | 0 | : BaseException(msg, file, line) {} |
210 | | /** |
211 | | @brief returns the class name of the exception instance |
212 | | @return the class name of the instance |
213 | | */ |
214 | 0 | const char* name() const noexcept override { return "SipMessage::Exception"; } |
215 | | }; |
216 | | |
217 | | /// Mark message as internally generated |
218 | | inline void setFromTU() |
219 | 0 | { |
220 | 0 | mIsExternal = false; |
221 | 0 | } |
222 | | |
223 | | /// Mark message as externally generated |
224 | | inline void setFromExternal() |
225 | 0 | { |
226 | 0 | mIsExternal = true; |
227 | 0 | } |
228 | | |
229 | | /** |
230 | | @brief Check if SipMessage is to be treated as it came off the wire. |
231 | | |
232 | | @return true if the message came from an IP interface or if it was |
233 | | an internally generated response to an internally generated |
234 | | request (ie: 408), false otherwise. |
235 | | */ |
236 | | inline bool isExternal() const |
237 | 0 | { |
238 | 0 | return mIsExternal; |
239 | 0 | } |
240 | | |
241 | | /** |
242 | | @brief Check if SipMessage came off the wire. |
243 | | |
244 | | @note differs from isExternal(), since isExternal() also returns true |
245 | | for internally generated responses to internally generate requests |
246 | | (ie: 408, etc.). isFromWire only ever returns true if the message |
247 | | actually came off the wire. |
248 | | |
249 | | @return true if the message came from an IP interface, false otherwise. |
250 | | */ |
251 | | inline bool isFromWire() const |
252 | 0 | { |
253 | 0 | return mReceivedTransportTuple.getType() != UNKNOWN_TRANSPORT; |
254 | 0 | } |
255 | | |
256 | | /// @brief Check if SipMessage is a client transaction |
257 | | /// @return true if the message is external and is a response or |
258 | | /// an internally-generated request. |
259 | | virtual bool isClientTransaction() const; |
260 | | |
261 | | /** @brief Generate a string from the SipMessage object |
262 | | |
263 | | @return string representation of a SIP message. |
264 | | */ |
265 | | virtual EncodeStream& encode(EncodeStream& str) const; |
266 | | //sipfrags will not output Content Length if there is no body--introduce |
267 | | //friendship to hide this? |
268 | | virtual EncodeStream& encodeSipFrag(EncodeStream& str) const; |
269 | | EncodeStream& encodeEmbedded(EncodeStream& str) const; |
270 | | |
271 | | virtual EncodeStream& encodeBrief(EncodeStream& str) const; |
272 | | EncodeStream& encodeSingleHeader(Headers::Type type, EncodeStream& str) const; |
273 | | |
274 | | /// Returns true if message is a request, false otherwise |
275 | 0 | inline bool isRequest() const {return mRequest;} |
276 | | /// Returns true if message is a response, false otherwise |
277 | 0 | inline bool isResponse() const {return mResponse;} |
278 | | /// Returns true if message failed to parse, false otherwise |
279 | 0 | inline bool isInvalid() const{return mInvalid;} |
280 | | |
281 | | /// @brief returns the method type of the message |
282 | | /// @see MethodTypes |
283 | | resip::MethodTypes method() const; |
284 | | /// Returns a string containing the SIP method for the message |
285 | | const Data& methodStr() const; |
286 | | |
287 | | /// Returns a string containing the response reason text |
288 | 0 | const resip::Data* getReason() const{return mReason;} |
289 | | |
290 | | /// Returns the RequestLine. This is only valid for request messages. |
291 | | const RequestLine& |
292 | | header(const RequestLineType& l) const; |
293 | | |
294 | | /// Returns the RequestLine. This is only valid for request messages. |
295 | | RequestLine& |
296 | | header(const RequestLineType& l); |
297 | | |
298 | | inline const RequestLine& |
299 | | const_header(const RequestLineType& l) const |
300 | 0 | { |
301 | 0 | return header(l); |
302 | 0 | } |
303 | | |
304 | | /// Returns the StatusLine. This is only valid for response messages. |
305 | | const StatusLine& |
306 | | header(const StatusLineType& l) const; |
307 | | |
308 | | /// Returns the StatusLine. This is only valid for response messages. |
309 | | StatusLine& |
310 | | header(const StatusLineType& l); |
311 | | |
312 | | inline const StatusLine& |
313 | | const_header(const StatusLineType& l) const |
314 | 0 | { |
315 | 0 | return header(l); |
316 | 0 | } |
317 | | |
318 | | /// Returns true if the given header field is present, false otherwise |
319 | | bool exists(const HeaderBase& headerType) const; |
320 | | /// Returns true if the header field is present and non-empty, false otherwise |
321 | | bool empty(const HeaderBase& headerType) const; |
322 | | /// @brief Prevents a header field from being present when the message is prepared |
323 | | /// for sending to a transport. This does not free the memory that was |
324 | | /// used by the header. |
325 | | inline void remove(const HeaderBase& headerType) |
326 | 0 | { |
327 | 0 | remove(headerType.getTypeNum()); |
328 | 0 | } |
329 | | |
330 | | void remove(Headers::Type type); |
331 | | |
332 | | #define defineHeader(_header, _name, _type, _rfc) \ |
333 | | const H_##_header::Type& header(const H_##_header& headerType) const; \ |
334 | | H_##_header::Type& header(const H_##_header& headerType); \ |
335 | | inline const H_##_header::Type& const_header(const H_##_header& headerType) const \ |
336 | 13.2k | {\ |
337 | 13.2k | return header(headerType);\ |
338 | 13.2k | } Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ContentDisposition const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ContentEncoding const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_MIMEVersion const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Priority const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Event const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SubscriptionState const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SIPETag const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SIPIfMatch const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ContentId const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ReferSub const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_AnswerMode const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PrivAnswerMode const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ContentType const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_IdentityInfo const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_From const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_To const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ReplyTo const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ReferTo const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ReferredBy const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PCalledPartyId const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ContentTransferEncoding const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Organization const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SecWebSocketKey const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SecWebSocketKey1 const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SecWebSocketKey2 const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Origin const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Host const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SecWebSocketAccept const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Server const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Subject const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_UserAgent const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Timestamp const&) const resip::SipMessage::const_header(resip::H_ContentLength const&) const Line | Count | Source | 336 | 13.2k | {\ | 337 | 13.2k | return header(headerType);\ | 338 | 13.2k | } |
Unexecuted instantiation: resip::SipMessage::const_header(resip::H_MaxForwards const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_MinExpires const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_RSeq const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_RetryAfter const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_FlowTimer const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Expires const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SessionExpires const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_MinSE const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_CallID const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Replaces const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_InReplyTo const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Join const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_TargetDialog const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_AuthenticationInfo const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_CSeq const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Date const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_RAck const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PChargingVector const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PChargingFunctionAddresses const&) const |
339 | | |
340 | | |
341 | | #define defineMultiHeader(_header, _name, _type, _rfc) \ |
342 | | const H_##_header##s::Type& header(const H_##_header##s& headerType) const; \ |
343 | | H_##_header##s::Type& header(const H_##_header##s& headerType); \ |
344 | | inline const H_##_header##s::Type& const_header(const H_##_header##s& headerType) const \ |
345 | 0 | {\ |
346 | 0 | return header(headerType);\ |
347 | 0 | } Unexecuted instantiation: resip::SipMessage::const_header(resip::H_AllowEventss const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Identitys const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_AcceptEncodings const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_AcceptLanguages const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Allows const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ContentLanguages const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ProxyRequires const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Requires const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Supporteds const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Unsupporteds const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SecurityClients const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SecurityServers const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_SecurityVerifys const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_RequestDispositions const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Reasons const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Privacys const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PMediaAuthorizations const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Accepts const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_CallInfos const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_AlertInfos const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ErrorInfos const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_RecordRoutes const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Routes const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Contacts const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Paths const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_AcceptContacts const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_RejectContacts const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PAssertedIdentitys const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PPreferredIdentitys const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PAssociatedUris const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ServiceRoutes const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_RemotePartyIds const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_HistoryInfos const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Cookies const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Authorizations const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ProxyAuthenticates const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_ProxyAuthorizations const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_WWWAuthenticates const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Warnings const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_Vias const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PAccessNetworkInfos const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_PVisitedNetworkIDs const&) const Unexecuted instantiation: resip::SipMessage::const_header(resip::H_UserToUsers const&) const |
348 | | |
349 | | defineHeader(ContentDisposition, "Content-Disposition", Token, "RFC 3261"); |
350 | | defineHeader(ContentEncoding, "Content-Encoding", Token, "RFC 3261"); |
351 | | defineHeader(MIMEVersion, "Mime-Version", Token, "RFC 3261"); |
352 | | defineHeader(Priority, "Priority", Token, "RFC 3261"); |
353 | | defineHeader(Event, "Event", Token, "RFC 3265"); |
354 | | defineHeader(SubscriptionState, "Subscription-State", Token, "RFC 3265"); |
355 | | defineHeader(SIPETag, "SIP-ETag", Token, "RFC 3903"); |
356 | | defineHeader(SIPIfMatch, "SIP-If-Match", Token, "RFC 3903"); |
357 | | defineHeader(ContentId, "Content-ID", Token, "RFC 2045"); |
358 | | defineMultiHeader(AllowEvents, "Allow-Events", Token, "RFC 3265"); |
359 | | defineMultiHeader(Identity, "Identity", StringCategory, "RFC 8224"); // Originally defined in RFC 4474 as a single header, but later modified by RFC8224 to be a multiheader |
360 | | defineMultiHeader(AcceptEncoding, "Accept-Encoding", Token, "RFC 3261"); |
361 | | defineMultiHeader(AcceptLanguage, "Accept-Language", Token, "RFC 3261"); |
362 | | defineMultiHeader(Allow, "Allow", Token, "RFC 3261"); |
363 | | defineMultiHeader(ContentLanguage, "Content-Language", Token, "RFC 3261"); |
364 | | defineMultiHeader(ProxyRequire, "Proxy-Require", Token, "RFC 3261"); |
365 | | defineMultiHeader(Require, "Require", Token, "RFC 3261"); |
366 | | defineMultiHeader(Supported, "Supported", Token, "RFC 3261"); |
367 | | defineMultiHeader(Unsupported, "Unsupported", Token, "RFC 3261"); |
368 | | defineMultiHeader(SecurityClient, "Security-Client", Token, "RFC 3329"); |
369 | | defineMultiHeader(SecurityServer, "Security-Server", Token, "RFC 3329"); |
370 | | defineMultiHeader(SecurityVerify, "Security-Verify", Token, "RFC 3329"); |
371 | | defineMultiHeader(RequestDisposition, "Request-Disposition", Token, "RFC 3841"); |
372 | | defineMultiHeader(Reason, "Reason", Token, "RFC 3326"); |
373 | | defineMultiHeader(Privacy, "Privacy", PrivacyCategory, "RFC 3323"); |
374 | | defineMultiHeader(PMediaAuthorization, "P-Media-Authorization", Token, "RFC 3313"); |
375 | | defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"); |
376 | | defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-04"); |
377 | | defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-04"); |
378 | | |
379 | | defineMultiHeader(Accept, "Accept", Mime, "RFC 3261"); |
380 | | defineHeader(ContentType, "Content-Type", Mime, "RFC 3261"); |
381 | | |
382 | | defineMultiHeader(CallInfo, "Call-Info", GenericUri, "RFC 3261"); |
383 | | defineMultiHeader(AlertInfo, "Alert-Info", GenericUri, "RFC 3261"); |
384 | | defineMultiHeader(ErrorInfo, "Error-Info", GenericUri, "RFC 3261"); |
385 | | defineHeader(IdentityInfo, "Identity-Info", GenericUri, "RFC 4474"); |
386 | | |
387 | | defineMultiHeader(RecordRoute, "Record-Route", NameAddr, "RFC 3261"); |
388 | | defineMultiHeader(Route, "Route", NameAddr, "RFC 3261"); |
389 | | defineMultiHeader(Contact, "Contact", NameAddr, "RFC 3261"); |
390 | | defineHeader(From, "From", NameAddr, "RFC 3261"); |
391 | | defineHeader(To, "To", NameAddr, "RFC 3261"); |
392 | | defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261"); |
393 | | defineHeader(ReferTo, "Refer-To", NameAddr, "RFC 3515"); |
394 | | defineHeader(ReferredBy, "Referred-By", NameAddr, "RFC 3892"); |
395 | | defineMultiHeader(Path, "Path", NameAddr, "RFC 3327"); |
396 | | defineMultiHeader(AcceptContact, "Accept-Contact", NameAddr, "RFC 3841"); |
397 | | defineMultiHeader(RejectContact, "Reject-Contact", NameAddr, "RFC 3841"); |
398 | | defineMultiHeader(PAssertedIdentity, "P-Asserted-Identity", NameAddr, "RFC 3325"); |
399 | | defineMultiHeader(PPreferredIdentity, "P-Preferred-Identity", NameAddr, "RFC 3325"); |
400 | | defineHeader(PCalledPartyId, "P-Called-Party-ID", NameAddr, "RFC 3455"); |
401 | | defineMultiHeader(PAssociatedUri, "P-Associated-URI", NameAddr, "RFC 3455"); |
402 | | defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608"); |
403 | | defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep? |
404 | | defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"); |
405 | | |
406 | | defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC 1521"); |
407 | | defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); |
408 | | defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455"); |
409 | | defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76"); |
410 | | defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76"); |
411 | | defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76"); |
412 | | defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76"); |
413 | | defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455"); |
414 | | defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265"); |
415 | | defineHeader(Server, "Server", StringCategory, "RFC 3261"); |
416 | | defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); |
417 | | defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); |
418 | | defineHeader(Timestamp, "Timestamp", StringCategory, "RFC 3261"); |
419 | | |
420 | | defineHeader(ContentLength, "Content-Length", UInt32Category, "RFC 3261"); |
421 | | defineHeader(MaxForwards, "Max-Forwards", UInt32Category, "RFC 3261"); |
422 | | defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261"); |
423 | | defineHeader(RSeq, "RSeq", UInt32Category, "RFC 3261"); |
424 | | |
425 | | /// @todo !dlb! this one is not quite right -- can have (comment) after field value |
426 | | defineHeader(RetryAfter, "Retry-After", UInt32Category, "RFC 3261"); |
427 | | defineHeader(FlowTimer, "Flow-Timer", UInt32Category, "RFC 5626"); |
428 | | |
429 | | defineHeader(Expires, "Expires", ExpiresCategory, "RFC 3261"); |
430 | | defineHeader(SessionExpires, "Session-Expires", ExpiresCategory, "RFC 4028"); |
431 | | defineHeader(MinSE, "Min-SE", ExpiresCategory, "RFC 4028"); |
432 | | |
433 | | defineHeader(CallID, "Call-ID", CallID, "RFC 3261"); |
434 | | defineHeader(Replaces, "Replaces", CallID, "RFC 3891"); |
435 | | defineHeader(InReplyTo, "In-Reply-To", CallID, "RFC 3261"); |
436 | | defineHeader(Join, "Join", CallId, "RFC 3911"); |
437 | | defineHeader(TargetDialog, "Target-Dialog", CallId, "RFC 4538"); |
438 | | |
439 | | defineHeader(AuthenticationInfo, "Authentication-Info", Auth, "RFC 3261"); |
440 | | defineMultiHeader(Authorization, "Authorization", Auth, "RFC 3261"); |
441 | | defineMultiHeader(ProxyAuthenticate, "Proxy-Authenticate", Auth, "RFC 3261"); |
442 | | defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261"); |
443 | | defineMultiHeader(WWWAuthenticate, "Www-Authenticate", Auth, "RFC 3261"); |
444 | | |
445 | | defineHeader(CSeq, "CSeq", CSeqCategory, "RFC 3261"); |
446 | | defineHeader(Date, "Date", DateCategory, "RFC 3261"); |
447 | | defineMultiHeader(Warning, "Warning", WarningCategory, "RFC 3261"); |
448 | | defineMultiHeader(Via, "Via", Via, "RFC 3261"); |
449 | | defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); |
450 | | |
451 | | defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"); // section 5.4. |
452 | | defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455"); |
453 | | defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455"); |
454 | | defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455"); |
455 | | |
456 | | defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); |
457 | | |
458 | | /// unknown header interface |
459 | | const StringCategories& header(const ExtensionHeader& symbol) const; |
460 | | StringCategories& header(const ExtensionHeader& symbol); |
461 | | bool exists(const ExtensionHeader& symbol) const; |
462 | | void remove(const ExtensionHeader& symbol); |
463 | | |
464 | | /// typeless header interface |
465 | | const HeaderFieldValueList* getRawHeader(Headers::Type headerType) const; |
466 | | void setRawHeader(const HeaderFieldValueList* hfvs, Headers::Type headerType); |
467 | 0 | const UnknownHeaders& getRawUnknownHeaders() const {return mUnknownHeaders;} |
468 | | /** |
469 | | Return the raw body string (if it exists). The returned HFV |
470 | | and its underlying memory is owned by the SipMessage, and may |
471 | | be released when this SipMessage is manipulated. |
472 | | |
473 | | This is a low-level interface; see getContents() for higher level. |
474 | | **/ |
475 | 0 | const HeaderFieldValue& getRawBody() const {return mContentsHfv;} |
476 | | |
477 | | /** |
478 | | Remove any existing body/contents, and (if non-empty) |
479 | | set the body to {body}. It makes full copy of the body |
480 | | to stored within the SipMessage (since lifetime of |
481 | | the message is unpredictable). |
482 | | |
483 | | This is a low-level interface; see setContents() for higher level. |
484 | | **/ |
485 | | void setRawBody(const HeaderFieldValue& body); |
486 | | |
487 | | /** @brief Retrieves the body of a SIP message. |
488 | | * |
489 | | * In the case of an INVITE request containing SDP, the body would |
490 | | * be an SdpContents. For a MESSAGE request, the body may be PlainContents, |
491 | | * CpimContents, or another subclass of Contents. |
492 | | * |
493 | | * @return pointer to the contents of the SIP message |
494 | | **/ |
495 | | Contents* getContents() const; |
496 | | /// Removes the contents from the message |
497 | | std::unique_ptr<Contents> releaseContents(); |
498 | | |
499 | | /// @brief Set the contents of the message |
500 | | /// @param contents to store in the message |
501 | | void setContents(const Contents* contents); |
502 | | /// @brief Set the contents of the message |
503 | | /// @param contents to store in the message |
504 | | void setContents(std::unique_ptr<Contents> contents); |
505 | | |
506 | | /// @internal transport interface |
507 | | void setStartLine(const char* start, int len); |
508 | | |
509 | | void setBody(const char* start, uint32_t len); |
510 | | |
511 | | /// Add HeaderFieldValue given enum, header name, pointer start, content length |
512 | | void addHeader(Headers::Type header, |
513 | | const char* headerName, int headerLen, |
514 | | const char* start, int len); |
515 | | |
516 | | // Returns the source tuple for the transport that the message was received from |
517 | | // only makes sense for messages received from the wire. Differs from Source |
518 | | // since it contains the transport bind address instead of the actual source |
519 | | // address. |
520 | 0 | const Tuple& getReceivedTransportTuple() const { return mReceivedTransportTuple; } |
521 | | |
522 | | /// Set Tuple for transport from whence this message came |
523 | 0 | void setReceivedTransportTuple(const Tuple& transportTuple) { mReceivedTransportTuple = transportTuple;} |
524 | | |
525 | | // Returns the source tuple that the message was received from |
526 | | // only makes sense for messages received from the wire |
527 | 0 | void setSource(const Tuple& tuple) { mSource = tuple; } |
528 | | /// @brief Returns the source tuple that the message was received from |
529 | | /// only makes sense for messages received from the wire |
530 | 0 | const Tuple& getSource() const { return mSource; } |
531 | | |
532 | | /// Used by the stateless interface to specify where to send a request/response |
533 | 0 | void setDestination(const Tuple& tuple) { mDestination = tuple; } |
534 | 0 | Tuple& getDestination() { return mDestination; } |
535 | | |
536 | | void addBuffer(char* buf); |
537 | | |
538 | 0 | uint64_t getCreatedTimeMicroSec() const {return mCreatedTime;} |
539 | | |
540 | | /// deal with a notion of an "out-of-band" forced target for SIP routing |
541 | | void setForceTarget(const Uri& uri); |
542 | | void clearForceTarget(); |
543 | | const Uri& getForceTarget() const; |
544 | | bool hasForceTarget() const; |
545 | | |
546 | 0 | const Data& getTlsDomain() const { return mTlsDomain; } |
547 | 0 | void setTlsDomain(const Data& domain) { mTlsDomain = domain; } |
548 | | |
549 | 0 | const std::list<Data>& getTlsPeerNames() const { return mTlsPeerNames; } |
550 | 0 | void setTlsPeerNames(const std::list<Data>& tlsPeerNames) { mTlsPeerNames = tlsPeerNames; } |
551 | | |
552 | 0 | const CookieList& getWsCookies() const { return mWsCookies; } |
553 | 0 | void setWsCookies(const CookieList& wsCookies) { mWsCookies = wsCookies; } |
554 | | |
555 | 0 | std::shared_ptr<WsCookieContext> getWsCookieContext() const noexcept { return mWsCookieContext; } |
556 | 0 | void setWsCookieContext(std::shared_ptr<WsCookieContext> wsCookieContext) noexcept { mWsCookieContext = wsCookieContext; } |
557 | | |
558 | | Data getCanonicalIdentityString() const; |
559 | | |
560 | | SipMessage& mergeUri(const Uri& source); |
561 | | |
562 | | void setSecurityAttributes(std::unique_ptr<SecurityAttributes>) noexcept; |
563 | 0 | const SecurityAttributes* getSecurityAttributes() const noexcept { return mSecurityAttributes.get(); } |
564 | | |
565 | | /// @brief Call a MessageDecorator to process the message before it is |
566 | | /// sent to the transport |
567 | 0 | void addOutboundDecorator(std::unique_ptr<MessageDecorator> md){mOutboundDecorators.push_back(md.release());} |
568 | | void clearOutboundDecorators(); |
569 | | void callOutboundDecorators(const Tuple &src, |
570 | | const Tuple &dest, |
571 | | const Data& sigcompId); |
572 | | void rollbackOutboundDecorators(); |
573 | | void copyOutboundDecoratorsToStackCancel(SipMessage& cancel); |
574 | | void copyOutboundDecoratorsToStackFailureAck(SipMessage& ack); |
575 | | bool mIsDecorated; |
576 | | |
577 | | bool mIsBadAck200; |
578 | | |
579 | | protected: |
580 | | // !bwc! Removes or zeros all pointers to heap-allocated memory this |
581 | | // class owns. |
582 | | void clear(bool leaveResponseStuff=false); |
583 | | // !bwc! Frees all heap-allocated memory owned. |
584 | | void freeMem(bool leaveResponseStuff=false); |
585 | | // Clears mHeaders and cleans up memory |
586 | | void clearHeaders(); |
587 | | |
588 | | // !bwc! Initializes members. Will not free heap-allocated memory. |
589 | | // Will begin by calling clear(). |
590 | | void init(const SipMessage& rhs); |
591 | | |
592 | | private: |
593 | | void compute2543TransactionHash() const; |
594 | | |
595 | | EncodeStream& |
596 | | encode(EncodeStream& str, bool isSipFrag) const; |
597 | | |
598 | | void copyFrom(const SipMessage& message); |
599 | | |
600 | | HeaderFieldValueList* ensureHeaders(Headers::Type type); |
601 | | inline HeaderFieldValueList* ensureHeaders(Headers::Type type) const // throws if not present |
602 | 0 | { |
603 | 0 | if(mHeaderIndices[type]>0) |
604 | 0 | { |
605 | 0 | return mHeaders[mHeaderIndices[type]]; |
606 | 0 | } |
607 | 0 | throwHeaderMissing(type); |
608 | 0 | return 0; |
609 | 0 | } |
610 | | |
611 | | HeaderFieldValueList* ensureHeader(Headers::Type type); |
612 | | inline HeaderFieldValueList* ensureHeader(Headers::Type type) const // throws if not present |
613 | 13.2k | { |
614 | 13.2k | if(mHeaderIndices[type]>0) |
615 | 13.2k | { |
616 | 13.2k | return mHeaders[mHeaderIndices[type]]; |
617 | 13.2k | } |
618 | 0 | throwHeaderMissing(type); |
619 | 0 | return 0; |
620 | 13.2k | } |
621 | | |
622 | | void throwHeaderMissing(Headers::Type type) const; |
623 | | |
624 | | inline HeaderFieldValueList* getEmptyHfvl() |
625 | 23.4k | { |
626 | 23.4k | void* ptr(mPool.allocate(sizeof(HeaderFieldValueList))); |
627 | 23.4k | return new (ptr) HeaderFieldValueList(mPool); |
628 | 23.4k | } |
629 | | |
630 | | inline HeaderFieldValueList* getCopyHfvl(const HeaderFieldValueList& hfvl) |
631 | 0 | { |
632 | 0 | void* ptr(mPool.allocate(sizeof(HeaderFieldValueList))); |
633 | 0 | return new (ptr) HeaderFieldValueList(hfvl, mPool); |
634 | 0 | } |
635 | | |
636 | | inline void freeHfvl(HeaderFieldValueList* hfvl) |
637 | 23.4k | { |
638 | 23.4k | if(hfvl) |
639 | 23.4k | { |
640 | 23.4k | hfvl->~HeaderFieldValueList(); |
641 | 23.4k | mPool.deallocate(hfvl); |
642 | 23.4k | } |
643 | 23.4k | } |
644 | | |
645 | | template<class T> |
646 | | ParserContainer<T>* makeParserContainer() |
647 | | { |
648 | | void* ptr(mPool.allocate(sizeof(ParserContainer<T>))); |
649 | | return new (ptr) ParserContainer<T>(mPool); |
650 | | } |
651 | | |
652 | | template<class T> |
653 | | ParserContainer<T>* makeParserContainer(HeaderFieldValueList* hfvs, |
654 | | Headers::Type type = Headers::UNKNOWN) |
655 | 253 | { |
656 | 253 | void* ptr(mPool.allocate(sizeof(ParserContainer<T>))); |
657 | 253 | return new (ptr) ParserContainer<T>(hfvs, type, mPool); |
658 | 253 | } Unexecuted instantiation: resip::ParserContainer<resip::StringCategory>* resip::SipMessage::makeParserContainer<resip::StringCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::Token>* resip::SipMessage::makeParserContainer<resip::Token>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::PrivacyCategory>* resip::SipMessage::makeParserContainer<resip::PrivacyCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::Mime>* resip::SipMessage::makeParserContainer<resip::Mime>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::GenericUri>* resip::SipMessage::makeParserContainer<resip::GenericUri>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::NameAddr>* resip::SipMessage::makeParserContainer<resip::NameAddr>(resip::HeaderFieldValueList*, resip::Headers::Type) resip::ParserContainer<resip::UInt32Category>* resip::SipMessage::makeParserContainer<resip::UInt32Category>(resip::HeaderFieldValueList*, resip::Headers::Type) Line | Count | Source | 655 | 253 | { | 656 | 253 | void* ptr(mPool.allocate(sizeof(ParserContainer<T>))); | 657 | 253 | return new (ptr) ParserContainer<T>(hfvs, type, mPool); | 658 | 253 | } |
Unexecuted instantiation: resip::ParserContainer<resip::ExpiresCategory>* resip::SipMessage::makeParserContainer<resip::ExpiresCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::CallID>* resip::SipMessage::makeParserContainer<resip::CallID>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::Auth>* resip::SipMessage::makeParserContainer<resip::Auth>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::CSeqCategory>* resip::SipMessage::makeParserContainer<resip::CSeqCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::DateCategory>* resip::SipMessage::makeParserContainer<resip::DateCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::WarningCategory>* resip::SipMessage::makeParserContainer<resip::WarningCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::Via>* resip::SipMessage::makeParserContainer<resip::Via>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::RAckCategory>* resip::SipMessage::makeParserContainer<resip::RAckCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) Unexecuted instantiation: resip::ParserContainer<resip::TokenOrQuotedStringCategory>* resip::SipMessage::makeParserContainer<resip::TokenOrQuotedStringCategory>(resip::HeaderFieldValueList*, resip::Headers::Type) |
659 | | |
660 | | // indicates this message came from the wire or we want it to look like it |
661 | | // came from the wire (ie. internally generated responses to an internally |
662 | | // generated request), set by the Transport and setFromTu and setFromExternal APIs |
663 | | bool mIsExternal; |
664 | | |
665 | | // Sizing so that average SipMessages don't need to allocate heap memory |
666 | | // To profile current sizing, enable DINKYPOOL_PROFILING in SipMessage.cxx |
667 | | // and look for DebugLog message in SipMessage destructor to know when heap |
668 | | // allocations are occuring and how much of the pool is used. |
669 | | DinkyPool<3732> mPool; |
670 | | |
671 | | typedef std::vector<HeaderFieldValueList*, |
672 | | StlPoolAllocator<HeaderFieldValueList*, |
673 | | PoolBase > > TypedHeaders; |
674 | | // raw text corresponding to each typed header (not yet parsed) |
675 | | TypedHeaders mHeaders; |
676 | | |
677 | | // !bwc! Indices into mHeaders |
678 | | short mHeaderIndices[Headers::MAX_HEADERS]; |
679 | | |
680 | | // raw text corresponding to each unknown header |
681 | | UnknownHeaders mUnknownHeaders; |
682 | | |
683 | | // For messages received from the wire, this indicates information about |
684 | | // the transport the message was received on |
685 | | Tuple mReceivedTransportTuple; |
686 | | |
687 | | // For messages received from the wire, this indicates where it came |
688 | | // from. Can be used to get to the Transport and/or reliable Connection |
689 | | Tuple mSource; |
690 | | |
691 | | // Used by the TU to specify where a message is to go |
692 | | Tuple mDestination; |
693 | | |
694 | | // Raw buffers coming from the Transport. message manages the memory |
695 | | std::vector<char*> mBufferList; |
696 | | |
697 | | // special case for the first line of message |
698 | | StartLine* mStartLine; |
699 | | char mStartLineMem[sizeof(RequestLine) > sizeof(StatusLine) ? sizeof(RequestLine) : sizeof(StatusLine)]; |
700 | | |
701 | | // raw text for the contents (all of them) |
702 | | HeaderFieldValue mContentsHfv; |
703 | | |
704 | | // lazy parser for the contents |
705 | | mutable Contents* mContents; |
706 | | |
707 | | // cached value of a hash of the transaction id for a message received |
708 | | // from a 2543 sip element. as per rfc3261 see 17.2.3 |
709 | | mutable Data mRFC2543TransactionId; |
710 | | |
711 | | // is a request or response |
712 | | bool mRequest; |
713 | | bool mResponse; |
714 | | |
715 | | bool mInvalid; |
716 | | resip::Data* mReason; |
717 | | |
718 | | uint64_t mCreatedTime; |
719 | | |
720 | | // used when next element is a strict router OR |
721 | | // client forces next hop OOB |
722 | | Uri* mForceTarget; |
723 | | |
724 | | // domain associated with this message for tls cert |
725 | | Data mTlsDomain; |
726 | | |
727 | | // peers domain associate with this message (MTLS) |
728 | | std::list<Data> mTlsPeerNames; |
729 | | |
730 | | // cookies associated with this message from the WebSocket Upgrade request |
731 | | CookieList mWsCookies; |
732 | | |
733 | | // parsed cookie authentication elements associated with this message from the WebSocket Upgrade request |
734 | | std::shared_ptr<WsCookieContext> mWsCookieContext; |
735 | | |
736 | | std::unique_ptr<SecurityAttributes> mSecurityAttributes; |
737 | | |
738 | | std::vector<MessageDecorator*> mOutboundDecorators; |
739 | | |
740 | | friend class TransportSelector; |
741 | | }; |
742 | | |
743 | | } |
744 | | |
745 | | #undef ensureHeaderTypeUseable |
746 | | #undef ensureSingleHeader |
747 | | #undef ensureMultiHeader |
748 | | #undef defineHeader |
749 | | #undef defineMultiHeader |
750 | | |
751 | | #endif |
752 | | |
753 | | /* ==================================================================== |
754 | | * The Vovida Software License, Version 1.0 |
755 | | * |
756 | | * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. |
757 | | * |
758 | | * Redistribution and use in source and binary forms, with or without |
759 | | * modification, are permitted provided that the following conditions |
760 | | * are met: |
761 | | * |
762 | | * 1. Redistributions of source code must retain the above copyright |
763 | | * notice, this list of conditions and the following disclaimer. |
764 | | * |
765 | | * 2. Redistributions in binary form must reproduce the above copyright |
766 | | * notice, this list of conditions and the following disclaimer in |
767 | | * the documentation and/or other materials provided with the |
768 | | * distribution. |
769 | | * |
770 | | * 3. The names "VOCAL", "Vovida Open Communication Application Library", |
771 | | * and "Vovida Open Communication Application Library (VOCAL)" must |
772 | | * not be used to endorse or promote products derived from this |
773 | | * software without prior written permission. For written |
774 | | * permission, please contact vocal@vovida.org. |
775 | | * |
776 | | * 4. Products derived from this software may not be called "VOCAL", nor |
777 | | * may "VOCAL" appear in their name, without prior written |
778 | | * permission of Vovida Networks, Inc. |
779 | | * |
780 | | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
781 | | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
782 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
783 | | * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
784 | | * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
785 | | * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
786 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
787 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
788 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
789 | | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
790 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
791 | | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
792 | | * DAMAGE. |
793 | | * |
794 | | * ==================================================================== |
795 | | * |
796 | | * This software consists of voluntary contributions made by Vovida |
797 | | * Networks, Inc. and many individuals on behalf of Vovida Networks, |
798 | | * Inc. For more information on Vovida Networks, Inc., please see |
799 | | * <http://www.vovida.org/>. |
800 | | * |
801 | | * vi: set shiftwidth=3 expandtab: |
802 | | */ |