|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include "resip/stack/MsgHeaderScanner.hxx" 00006 #include "resip/stack/SipFrag.hxx" 00007 #include "resip/stack/SipMessage.hxx" 00008 #include "rutil/Logger.hxx" 00009 #include "rutil/ParseBuffer.hxx" 00010 #include "rutil/WinLeakCheck.hxx" 00011 00012 using namespace resip; 00013 using namespace std; 00014 00015 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00016 00017 bool 00018 SipFrag::init() 00019 { 00020 static ContentsFactory<SipFrag> factory; 00021 (void)factory; 00022 return true; 00023 } 00024 00025 SipFrag::SipFrag(const Mime& contentsType) 00026 : Contents(contentsType), 00027 mMessage(new SipMessage()) 00028 {} 00029 00030 SipFrag::SipFrag(const HeaderFieldValue& hfv, const Mime& contentsType) 00031 : Contents(hfv, HeaderFieldValue::CopyPadding, contentsType), 00032 mMessage(0) 00033 { 00034 } 00035 00036 SipFrag::SipFrag(const SipFrag& rhs) 00037 : Contents(rhs,HeaderFieldValue::CopyPadding), 00038 mMessage(rhs.mMessage ? new SipMessage(*rhs.mMessage) : 0) 00039 { 00040 } 00041 00042 SipFrag::~SipFrag() 00043 { 00044 delete mMessage; 00045 } 00046 00047 SipFrag& 00048 SipFrag::operator=(const SipFrag& rhs) 00049 { 00050 if (this != &rhs) 00051 { 00052 Contents::operator=(rhs); 00053 delete mMessage; 00054 if (rhs.mMessage) 00055 { 00056 mMessage = new SipMessage(*rhs.mMessage); 00057 } 00058 else 00059 { 00060 mMessage = 0; 00061 } 00062 } 00063 00064 return *this; 00065 } 00066 00067 Contents* 00068 SipFrag::clone() const 00069 { 00070 return new SipFrag(*this); 00071 } 00072 00073 const Mime& 00074 SipFrag::getStaticType() 00075 { 00076 static Mime type("message", "sipfrag"); 00077 //static Mime type("application", "sipfrag"); 00078 return type; 00079 } 00080 00081 SipMessage& 00082 SipFrag::message() 00083 { 00084 checkParsed(); 00085 return *mMessage; 00086 } 00087 00088 const SipMessage& 00089 SipFrag::message() const 00090 { 00091 checkParsed(); 00092 return *mMessage; 00093 } 00094 00095 EncodeStream& 00096 SipFrag::encodeParsed(EncodeStream& str) const 00097 { 00098 mMessage->encodeSipFrag(str); 00099 00100 return str; 00101 } 00102 00103 bool 00104 SipFrag::hasStartLine(char* buffer, int size) 00105 { 00106 #if 0 00107 00108 //difficult. Better here than in the MsgHeaderScanner. There's also proabably a 00109 //way to make a header that matches the requestLine check which isn't a 00110 //request line. 00111 00112 ParseBuffer pbCheck(buffer, size); 00113 pbCheck.skipWhitespace(); //gratuitous? 00114 00116 if ((pbCheck.end() - pbCheck.position()) > 4 && 00117 strncmp(pbCheck.position(), "SIP/", 4) == 0) 00118 { 00119 return true; 00120 } 00121 else 00122 { 00123 pbCheck.skipToChars(Symbols::CRLF); 00124 if (pbCheck.eof()) 00125 { 00126 //false positive, let MsgHeaderScanner sort the exact error out 00127 return true; 00128 } 00129 00130 pbCheck.skipBackToChar(Symbols::SPACE[0]); 00131 if (pbCheck.position() == pbCheck.start()) 00132 { 00133 return false; 00134 } 00135 00136 if ((pbCheck.end() - pbCheck.position()) > 4 && 00137 strncmp(pbCheck.position(), "SIP/", 4) == 0) 00138 { 00139 return true; 00140 } 00141 else 00142 { 00143 return false; 00144 } 00145 } 00146 #else 00147 00148 ParseBuffer pbCheck(buffer, size); 00149 pbCheck.skipWhitespace(); //gratuitous? 00150 pbCheck.skipToOneOf(" \t:\r\n"); 00151 while(!pbCheck.eof()) 00152 { 00153 switch(*pbCheck.position()) 00154 { 00155 case ':': 00156 return false; 00157 case ' ': 00158 case '\t': 00159 pbCheck.skipChar(); 00160 break; 00161 case '\r': 00162 case '\n': 00163 return false; 00164 default: 00165 return true; 00166 } 00167 } 00168 return true; //false positive, let MsgHeaderScanner sort the exact error out 00169 #endif 00170 } 00171 00172 void 00173 SipFrag::parse(ParseBuffer& pb) 00174 { 00175 // DebugLog(<< "SipFrag::parse: " << pb.position()); 00176 00177 mMessage = new SipMessage(); 00178 00179 pb.assertNotEof(); 00180 const char *constBuffer = pb.position(); 00181 char *buffer = const_cast<char *>(constBuffer); 00182 00183 size_t size = pb.end() - pb.position(); 00184 00185 // !ah! removed size check .. process() cannot process more 00186 // than size bytes of the message. 00187 00188 00189 MsgHeaderScanner msgHeaderScanner; 00190 msgHeaderScanner.prepareForFrag(mMessage, hasStartLine(buffer, (int)size)); 00191 enum { sentinelLength = 4 }; // Two carriage return / line feed pairs. 00192 //char saveTermCharArray[sentinelLength]; 00193 static const char* sentinel="\r\n\r\n"; 00194 char *termCharArray = buffer + size; 00195 memcpy(scratchpad,termCharArray,4); 00196 00197 /*saveTermCharArray[0] = termCharArray[0]; 00198 saveTermCharArray[1] = termCharArray[1]; 00199 saveTermCharArray[2] = termCharArray[2]; 00200 saveTermCharArray[3] = termCharArray[3];*/ 00201 00202 memcpy(termCharArray,sentinel,4); 00203 /*termCharArray[0] = '\r'; 00204 termCharArray[1] = '\n'; 00205 termCharArray[2] = '\r'; 00206 termCharArray[3] = '\n';*/ 00207 char *scanTermCharPtr; 00208 MsgHeaderScanner::ScanChunkResult scanChunkResult = 00209 msgHeaderScanner.scanChunk(buffer, 00210 (unsigned int)(size + sentinelLength), 00211 &scanTermCharPtr); 00212 00213 memcpy(termCharArray,scratchpad,4); 00214 /*termCharArray[0] = saveTermCharArray[0]; 00215 termCharArray[1] = saveTermCharArray[1]; 00216 termCharArray[2] = saveTermCharArray[2]; 00217 termCharArray[3] = saveTermCharArray[3];*/ 00218 00219 // !dlb! not at all clear what to do here 00220 // see: "// tests end of message problem (MsgHeaderScanner?)" 00221 // in test/testSipFrag.cxx 00222 if (false && scanChunkResult != MsgHeaderScanner::scrEnd) 00223 { 00224 CerrLog(<< "not MsgHeaderScanner::scrEnd"); 00225 pb.fail(__FILE__, __LINE__); 00226 } 00227 else 00228 { 00229 size_t used = scanTermCharPtr - buffer; 00230 00231 // !ah! I think this is broken .. if we are UDP then the 00232 // remainder is the SigFrag, not the Content-Length... ?? 00233 if (mMessage->exists(h_ContentLength)) 00234 { 00235 mMessage->setBody(scanTermCharPtr, 00236 static_cast<int>(size - used)); 00237 } 00238 else 00239 { 00240 // !ah! So the headers weren't complete. Why are we here? 00241 // !dlb! 00242 if (mMessage->exists(h_ContentLength)) 00243 { 00244 pb.reset(buffer + used); 00245 pb.skipChars(Symbols::CRLF); 00246 mMessage->setBody(pb.position(),int(pb.end()-pb.position()) ); 00247 } 00248 } 00249 pb.reset(pb.end()); 00250 } 00251 } 00252 00253 /* ==================================================================== 00254 * The Vovida Software License, Version 1.0 00255 * 00256 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00257 * 00258 * Redistribution and use in source and binary forms, with or without 00259 * modification, are permitted provided that the following conditions 00260 * are met: 00261 * 00262 * 1. Redistributions of source code must retain the above copyright 00263 * notice, this list of conditions and the following disclaimer. 00264 * 00265 * 2. Redistributions in binary form must reproduce the above copyright 00266 * notice, this list of conditions and the following disclaimer in 00267 * the documentation and/or other materials provided with the 00268 * distribution. 00269 * 00270 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00271 * and "Vovida Open Communication Application Library (VOCAL)" must 00272 * not be used to endorse or promote products derived from this 00273 * software without prior written permission. For written 00274 * permission, please contact vocal@vovida.org. 00275 * 00276 * 4. Products derived from this software may not be called "VOCAL", nor 00277 * may "VOCAL" appear in their name, without prior written 00278 * permission of Vovida Networks, Inc. 00279 * 00280 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00281 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00282 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00283 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00284 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00285 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00286 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00287 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00288 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00289 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00290 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00291 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00292 * DAMAGE. 00293 * 00294 * ==================================================================== 00295 * 00296 * This software consists of voluntary contributions made by Vovida 00297 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00298 * Inc. For more information on Vovida Networks, Inc., please see 00299 * <http://www.vovida.org/>. 00300 * 00301 */
1.7.5.1