|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include <cassert> 00006 #include "resip/stack/BranchParameter.hxx" 00007 #include "resip/stack/Symbols.hxx" 00008 #include "rutil/ParseBuffer.hxx" 00009 #include "rutil/Random.hxx" 00010 #include "rutil/Coders.hxx" 00011 #include "rutil/ParseException.hxx" 00012 00013 #include "rutil/Logger.hxx" 00014 #include "rutil/WinLeakCheck.hxx" 00015 00016 using namespace resip; 00017 using namespace std; 00018 00019 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00020 00021 BranchParameter::BranchParameter(ParameterTypes::Type type, 00022 ParseBuffer& pb, 00023 const std::bitset<256>& terminators) 00024 : Parameter(type), 00025 mHasMagicCookie(false), 00026 mIsMyBranch(false), 00027 mTransactionId(), 00028 mTransportSeq(1), 00029 mClientData(), 00030 mInteropMagicCookie(0), 00031 mSigcompCompartment() 00032 { 00033 try 00034 { 00035 pb.skipWhitespace(); 00036 pb.skipChar(Symbols::EQUALS[0]); 00037 pb.skipWhitespace(); 00038 if(memcmp(pb.position(), Symbols::MagicCookie, 7) == 0) 00039 { 00040 mHasMagicCookie=true; 00041 pb.skipN(7); 00042 } 00043 // !bwc! This no-case comparison is expensive; only do it if the case- 00044 // sensitive comparison fails. 00045 else if(strncasecmp(pb.position(), Symbols::MagicCookie, 7) == 0) 00046 { 00047 mHasMagicCookie=true; 00048 mInteropMagicCookie = new Data(pb.position(), 7); 00049 pb.skipN(7); 00050 } 00051 00052 const char* start = pb.position(); 00053 static std::bitset<256> delimiter=Data::toBitset("\r\n\t ;=?>"); 00054 00055 if (mHasMagicCookie && 00056 (pb.end() - start > 8) && 00057 // look for prefix cookie (maybe make this bigger?) 00058 memcmp(start, Symbols::resipCookie, 8) == 0) 00059 { 00060 // ?bwc? Wrap this stuff in try/catch, just in case of false positives? 00061 const char* curr=start; 00062 mIsMyBranch = true; 00063 pb.skipN(8); 00064 00065 mTransportSeq=pb.uInt32(); 00066 00067 curr=pb.skipChar('-'); 00068 pb.skipToChar('-'); 00069 Data encoded; 00070 pb.data(encoded, curr); 00071 if(!encoded.empty()) 00072 { 00073 // !bwc! Expensive! Also, Base64 isn't case-insensitive. 00074 mClientData = encoded.base64decode(); 00075 } 00076 00077 curr=pb.skipChar('-'); 00078 pb.skipToChar('-'); 00079 pb.data(encoded,curr); 00080 if(!encoded.empty()) 00081 { 00082 // !bwc! Expensive! Also, Base64 isn't case-insensitive. 00083 mSigcompCompartment = encoded.base64decode(); 00084 } 00085 00086 start=pb.skipChar('-'); 00087 } 00088 pb.skipToOneOf(delimiter); 00089 pb.data(mTransactionId, start); 00090 } 00091 catch(resip::ParseException& e) 00092 { 00093 mTransactionId=Random::getRandomHex(8); 00094 throw e; 00095 } 00096 } 00097 00098 BranchParameter::BranchParameter(ParameterTypes::Type type) 00099 : Parameter(type), 00100 mHasMagicCookie(true), 00101 mIsMyBranch(true), 00102 mTransactionId(Random::getRandomHex(8)), 00103 mTransportSeq(1), 00104 mInteropMagicCookie(0), 00105 mSigcompCompartment() 00106 { 00107 } 00108 00109 BranchParameter::BranchParameter(const BranchParameter& other) 00110 : Parameter(other), 00111 mHasMagicCookie(other.mHasMagicCookie), 00112 mIsMyBranch(other.mIsMyBranch), 00113 mTransactionId(other.mTransactionId), 00114 mTransportSeq(other.mTransportSeq), 00115 mClientData(other.mClientData), 00116 mSigcompCompartment(other.mSigcompCompartment) 00117 { 00118 if (other.mInteropMagicCookie) 00119 { 00120 mInteropMagicCookie = new Data(*other.mInteropMagicCookie); 00121 } 00122 else 00123 { 00124 mInteropMagicCookie = 0; 00125 } 00126 } 00127 00128 BranchParameter::~BranchParameter() 00129 { 00130 delete mInteropMagicCookie; 00131 } 00132 00133 BranchParameter& 00134 BranchParameter::operator=(const BranchParameter& other) 00135 { 00136 if (this != &other) 00137 { 00138 mHasMagicCookie = other.mHasMagicCookie; 00139 mIsMyBranch = other.mIsMyBranch; 00140 mTransactionId = other.mTransactionId; 00141 mTransportSeq = other.mTransportSeq; 00142 mClientData = other.mClientData; 00143 mSigcompCompartment = other.mSigcompCompartment; 00144 if (other.mInteropMagicCookie) 00145 { 00146 delete mInteropMagicCookie; 00147 mInteropMagicCookie = new Data(*other.mInteropMagicCookie); 00148 } 00149 else 00150 { 00151 delete mInteropMagicCookie; 00152 mInteropMagicCookie = 0; 00153 } 00154 } 00155 return *this; 00156 } 00157 00158 bool 00159 BranchParameter::operator==(const BranchParameter& other) 00160 { 00161 if (mIsMyBranch != other.mIsMyBranch || 00162 mHasMagicCookie != other.mHasMagicCookie || 00163 mTransportSeq != other.mTransportSeq || 00164 mTransactionId != other.mTransactionId || 00165 mClientData != other.mClientData || 00166 mSigcompCompartment != other.mSigcompCompartment) 00167 { 00168 return false; 00169 } 00170 return true; 00171 } 00172 00173 bool 00174 BranchParameter::hasMagicCookie() const 00175 { 00176 return mHasMagicCookie; 00177 } 00178 00179 const Data& 00180 BranchParameter::getTransactionId() const 00181 { 00182 return mTransactionId; 00183 } 00184 00185 void 00186 BranchParameter::incrementTransportSequence() 00187 { 00188 assert(mIsMyBranch); 00189 mTransportSeq++; 00190 } 00191 00192 Data& 00193 BranchParameter::clientData() 00194 { 00195 return mClientData; 00196 } 00197 00198 const Data& 00199 BranchParameter::clientData() const 00200 { 00201 return mClientData; 00202 } 00203 00207 void 00208 BranchParameter::setSigcompCompartment(const Data &id) 00209 { 00210 if (id.size() == 0) 00211 { 00212 mSigcompCompartment = Data::Empty; 00213 } 00214 00215 // These will often (but not always) be UUID URNs in angle brackets; 00216 // e.g.: <urn:uuid:fa33c72d-121f-47e8-42e2-1eb6e24aba64> 00217 00218 // Ideally, we would detect this, strip out everything that isn't 00219 // hex, and convert the hex to raw data. 00220 00221 mSigcompCompartment = id; 00222 } 00223 00224 Data 00225 BranchParameter::getSigcompCompartment() const 00226 { 00227 return mSigcompCompartment; 00228 } 00229 00230 void 00231 BranchParameter::reset(const Data& transactionId) 00232 { 00233 mHasMagicCookie = true; 00234 mIsMyBranch = true; 00235 delete mInteropMagicCookie; 00236 mInteropMagicCookie = 0; 00237 00238 mSigcompCompartment = Data::Empty; 00239 00240 mTransportSeq = 1; 00241 if (!transactionId.empty()) 00242 { 00243 mTransactionId = transactionId; 00244 } 00245 else 00246 { 00247 mTransactionId = Random::getRandomHex(8); 00248 } 00249 } 00250 00251 Parameter* 00252 BranchParameter::clone() const 00253 { 00254 return new BranchParameter(*this); 00255 } 00256 00257 EncodeStream& 00258 BranchParameter::encode(EncodeStream& stream) const 00259 { 00260 stream << getName() << Symbols::EQUALS; 00261 if (mHasMagicCookie) 00262 { 00263 if (mInteropMagicCookie) 00264 { 00265 stream << *mInteropMagicCookie; 00266 } 00267 else 00268 { 00269 stream << Symbols::MagicCookie; 00270 } 00271 } 00272 if (mIsMyBranch) 00273 { 00274 stream << Symbols::resipCookie; 00275 stream << mTransportSeq; 00276 stream << Symbols::DASH; 00277 if(!mClientData.empty()) // base64encode() makes copies 00278 { 00279 // !bwc! We should be using hex encoding; branch params are supposed to 00280 // be case-insensitive. 00281 stream << mClientData.base64encode(true/*safe URL*/); 00282 } 00283 stream << Symbols::DASH; 00284 if(!mSigcompCompartment.empty()) // base64encode() makes copies 00285 { 00286 // !bwc! We should be using hex encoding; branch params are supposed to 00287 // be case-insensitive. 00288 stream << mSigcompCompartment.base64encode(true); 00289 } 00290 stream << Symbols::DASH; 00291 } 00292 stream << mTransactionId; 00293 00294 return stream; 00295 } 00296 00297 00298 /* ==================================================================== 00299 * The Vovida Software License, Version 1.0 00300 * 00301 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00302 * 00303 * Redistribution and use in source and binary forms, with or without 00304 * modification, are permitted provided that the following conditions 00305 * are met: 00306 * 00307 * 1. Redistributions of source code must retain the above copyright 00308 * notice, this list of conditions and the following disclaimer. 00309 * 00310 * 2. Redistributions in binary form must reproduce the above copyright 00311 * notice, this list of conditions and the following disclaimer in 00312 * the documentation and/or other materials provided with the 00313 * distribution. 00314 * 00315 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00316 * and "Vovida Open Communication Application Library (VOCAL)" must 00317 * not be used to endorse or promote products derived from this 00318 * software without prior written permission. For written 00319 * permission, please contact vocal@vovida.org. 00320 * 00321 * 4. Products derived from this software may not be called "VOCAL", nor 00322 * may "VOCAL" appear in their name, without prior written 00323 * permission of Vovida Networks, Inc. 00324 * 00325 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00326 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00327 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00328 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00329 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00330 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00331 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00332 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00333 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00334 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00335 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00336 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00337 * DAMAGE. 00338 * 00339 * ==================================================================== 00340 * 00341 * This software consists of voluntary contributions made by Vovida 00342 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00343 * Inc. For more information on Vovida Networks, Inc., please see 00344 * <http://www.vovida.org/>. 00345 * 00346 */
1.7.5.1