reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
SipFrag.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
8#include "rutil/Logger.hxx"
11
12using namespace resip;
13using namespace std;
14
15#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
16
17bool
19{
20 static ContentsFactory<SipFrag> factory;
21 (void)factory;
22 return true;
23}
24
25SipFrag::SipFrag(const Mime& contentsType)
26 : Contents(contentsType),
27 mMessage(new SipMessage())
28{}
29
30SipFrag::SipFrag(const HeaderFieldValue& hfv, const Mime& contentsType)
31 : Contents(hfv, HeaderFieldValue::CopyPadding, contentsType),
32 mMessage(0)
33{
34}
35
37 : Contents(rhs,HeaderFieldValue::CopyPadding),
38 mMessage(rhs.mMessage ? new SipMessage(*rhs.mMessage) : 0)
39{
40}
41
43{
44 delete mMessage;
45}
46
49{
50 if (this != &rhs)
51 {
53 delete mMessage;
54 if (rhs.mMessage)
55 {
56 mMessage = new SipMessage(*rhs.mMessage);
57 }
58 else
59 {
60 mMessage = 0;
61 }
62 }
63
64 return *this;
65}
66
69{
70 return new SipFrag(*this);
71}
72
73const Mime&
75{
76 static Mime type("message", "sipfrag");
77 //static Mime type("application", "sipfrag");
78 return type;
79}
80
83{
84 checkParsed();
85 return *mMessage;
86}
87
88const SipMessage&
90{
91 checkParsed();
92 return *mMessage;
93}
94
96SipFrag::encodeParsed(EncodeStream& str) const
97{
98 mMessage->encodeSipFrag(str);
99
100 return str;
101}
102
103bool
104SipFrag::hasStartLine(char* buffer, int size)
105{
106#if 0
108 //difficult. Better here than in the MsgHeaderScanner. There's also proabably a
109 //way to make a header that matches the requestLine check which isn't a
110 //request line.
111
112 ParseBuffer pbCheck(buffer, size);
113 pbCheck.skipWhitespace(); //gratuitous?
114
116 if ((pbCheck.end() - pbCheck.position()) > 4 &&
117 strncmp(pbCheck.position(), "SIP/", 4) == 0)
118 {
119 return true;
120 }
121 else
122 {
123 pbCheck.skipToChars(Symbols::CRLF);
124 if (pbCheck.eof())
125 {
126 //false positive, let MsgHeaderScanner sort the exact error out
127 return true;
128 }
129
130 pbCheck.skipBackToChar(Symbols::SPACE[0]);
131 if (pbCheck.position() == pbCheck.start())
132 {
133 return false;
134 }
135
136 if ((pbCheck.end() - pbCheck.position()) > 4 &&
137 strncmp(pbCheck.position(), "SIP/", 4) == 0)
138 {
139 return true;
140 }
141 else
142 {
143 return false;
144 }
145 }
146#else
148 ParseBuffer pbCheck(buffer, size);
149 pbCheck.skipWhitespace(); //gratuitous?
150 pbCheck.skipToOneOf(" \t:\r\n");
151 while(!pbCheck.eof())
152 {
153 switch(*pbCheck.position())
154 {
155 case ':':
156 return false;
157 case ' ':
158 case '\t':
159 pbCheck.skipChar();
160 break;
161 case '\r':
162 case '\n':
163 return false;
164 default:
165 return true;
166 }
167 }
168 return true; //false positive, let MsgHeaderScanner sort the exact error out
169#endif
170}
171
172void
174{
175// DebugLog(<< "SipFrag::parse: " << pb.position());
176
177 mMessage = new SipMessage();
178
179 pb.assertNotEof();
180 const char *constBuffer = pb.position();
181 char *buffer = const_cast<char *>(constBuffer);
182
183 size_t size = pb.end() - pb.position();
184
185 // !ah! removed size check .. process() cannot process more
186 // than size bytes of the message.
187
188
189 MsgHeaderScanner msgHeaderScanner;
190 msgHeaderScanner.prepareForFrag(mMessage, hasStartLine(buffer, (int)size));
191 enum { sentinelLength = 4 }; // Two carriage return / line feed pairs.
192 //char saveTermCharArray[sentinelLength];
193 static const char* sentinel="\r\n\r\n";
194 char *termCharArray = buffer + size;
195 memcpy(scratchpad,termCharArray,4);
196
197 /*saveTermCharArray[0] = termCharArray[0];
198 saveTermCharArray[1] = termCharArray[1];
199 saveTermCharArray[2] = termCharArray[2];
200 saveTermCharArray[3] = termCharArray[3];*/
201
202 memcpy(termCharArray,sentinel,4);
203 /*termCharArray[0] = '\r';
204 termCharArray[1] = '\n';
205 termCharArray[2] = '\r';
206 termCharArray[3] = '\n';*/
207 char *scanTermCharPtr;
208 MsgHeaderScanner::ScanChunkResult scanChunkResult =
209 msgHeaderScanner.scanChunk(buffer,
210 (unsigned int)(size + sentinelLength),
211 &scanTermCharPtr);
212
213 memcpy(termCharArray,scratchpad,4);
214 /*termCharArray[0] = saveTermCharArray[0];
215 termCharArray[1] = saveTermCharArray[1];
216 termCharArray[2] = saveTermCharArray[2];
217 termCharArray[3] = saveTermCharArray[3];*/
218
219 // !dlb! not at all clear what to do here
220 // see: "// tests end of message problem (MsgHeaderScanner?)"
221 // in test/testSipFrag.cxx
222 if (false && scanChunkResult != MsgHeaderScanner::scrEnd)
223 {
224 CerrLog(<< "not MsgHeaderScanner::scrEnd");
225 pb.fail(__FILE__, __LINE__);
226 }
227 else
228 {
229 size_t used = scanTermCharPtr - buffer;
230
231 // !ah! I think this is broken .. if we are UDP then the
232 // remainder is the SigFrag, not the Content-Length... ??
233 if (mMessage->exists(h_ContentLength))
234 {
235 mMessage->setBody(scanTermCharPtr,
236 static_cast<int>(size - used));
237 }
238 else
239 {
240 // !ah! So the headers weren't complete. Why are we here?
241 // !dlb!
242 if (mMessage->exists(h_ContentLength))
243 {
244 pb.reset(buffer + used);
246 mMessage->setBody(pb.position(),int(pb.end()-pb.position()) );
247 }
248 }
249 pb.reset(pb.end());
250 }
251}
252
253/* ====================================================================
254 * The Vovida Software License, Version 1.0
255 *
256 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
257 *
258 * Redistribution and use in source and binary forms, with or without
259 * modification, are permitted provided that the following conditions
260 * are met:
261 *
262 * 1. Redistributions of source code must retain the above copyright
263 * notice, this list of conditions and the following disclaimer.
264 *
265 * 2. Redistributions in binary form must reproduce the above copyright
266 * notice, this list of conditions and the following disclaimer in
267 * the documentation and/or other materials provided with the
268 * distribution.
269 *
270 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
271 * and "Vovida Open Communication Application Library (VOCAL)" must
272 * not be used to endorse or promote products derived from this
273 * software without prior written permission. For written
274 * permission, please contact vocal@vovida.org.
275 *
276 * 4. Products derived from this software may not be called "VOCAL", nor
277 * may "VOCAL" appear in their name, without prior written
278 * permission of Vovida Networks, Inc.
279 *
280 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
281 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
282 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
283 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
284 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
285 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
286 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
287 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
288 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
289 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
290 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
291 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
292 * DAMAGE.
293 *
294 * ====================================================================
295 *
296 * This software consists of voluntary contributions made by Vovida
297 * Networks, Inc. and many individuals on behalf of Vovida Networks,
298 * Inc. For more information on Vovida Networks, Inc., please see
299 * <http://www.vovida.org/>.
300 *
301 */
#define CerrLog(args_)
Definition Logger.hxx:120
Base class for all SIP body types.
Definition Contents.hxx:51
Contents & operator=(const Contents &rhs)
Assignment operator.
Definition Contents.cxx:71
void checkParsed() const
Represents the "media-type" element in the RFC 3261 grammar.
Definition Mime.hxx:20
void prepareForFrag(SipMessage *msg, bool hasStartLine)
MsgHeaderScanner::ScanChunkResult scanChunk(char *chunk, unsigned int chunkLength, char **unprocessedCharPtr)
Provides string-parsing functionality with protection from buffer overflow.
Pointer end() const
CurrentPosition position() const
void reset(const char *pos)
CurrentPosition skipChars(const char *cs)
void assertNotEof() const
void fail(const char *file, unsigned int line, const Data &errmsg=Data::Empty) const
SIP body type for holding SipFrag contents (MIME content-type message/sipfrag).
Definition SipFrag.hxx:22
SipFrag & operator=(const SipFrag &rhs)
Definition SipFrag.cxx:48
virtual void parse(ParseBuffer &pb)
Definition SipFrag.cxx:173
virtual ~SipFrag()
Definition SipFrag.cxx:42
SipMessage & message()
Definition SipFrag.cxx:82
static bool init()
Definition SipFrag.cxx:18
virtual EncodeStream & encodeParsed(EncodeStream &str) const
Definition SipFrag.cxx:96
SipFrag(const Mime &contentsType=getStaticType())
Definition SipFrag.cxx:25
static const Mime & getStaticType()
Definition SipFrag.cxx:74
virtual Contents * clone() const
duplicate an SipFrag object
Definition SipFrag.cxx:68
Represents a SIP message.
void setBody(const char *start, uint32_t len)
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
virtual EncodeStream & encodeSipFrag(EncodeStream &str) const
static const char * SPACE
Definition Symbols.hxx:34
static const char * CRLF
Definition Symbols.hxx:21
dcm! – add UnusedChecking(_enum) below;
#define EncodeStream