|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include "resip/stack/Via.hxx" 00006 #include "rutil/DnsUtil.hxx" 00007 #include "rutil/Logger.hxx" 00008 #include "rutil/ParseBuffer.hxx" 00009 //#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below 00010 00011 using namespace resip; 00012 using namespace std; 00013 00014 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00015 00016 00017 //==================== 00018 // Via: 00019 //==================== 00020 Via::Via() 00021 : ParserCategory(), 00022 mProtocolName(Data::Share,Symbols::ProtocolName), 00023 mProtocolVersion(Data::Share,Symbols::ProtocolVersion), 00024 mTransport(), 00025 mSentHost(), 00026 mSentPort(0) 00027 { 00028 // insert a branch in all Vias (default constructor) 00029 this->param(p_branch); 00030 this->param(p_rport); // add the rport parameter by default as per rfc 3581 00031 } 00032 00033 Via::Via(const HeaderFieldValue& hfv, 00034 Headers::Type type, 00035 PoolBase* pool) 00036 : ParserCategory(hfv, type, pool), 00037 mProtocolName(Data::Share,Symbols::ProtocolName), 00038 mProtocolVersion(Data::Share,Symbols::ProtocolVersion), 00039 mTransport(Data::Share,Symbols::UDP), // !jf! 00040 mSentHost(), 00041 mSentPort(-1) 00042 {} 00043 00044 Via::Via(const Via& rhs, 00045 PoolBase* pool) 00046 : ParserCategory(rhs, pool), 00047 mProtocolName(rhs.mProtocolName), 00048 mProtocolVersion(rhs.mProtocolVersion), 00049 mTransport(rhs.mTransport), 00050 mSentHost(rhs.mSentHost), 00051 mSentPort(rhs.mSentPort) 00052 { 00053 } 00054 00055 Via& 00056 Via::operator=(const Via& rhs) 00057 { 00058 if (this != &rhs) 00059 { 00060 ParserCategory::operator=(rhs); 00061 mProtocolName = rhs.mProtocolName; 00062 mProtocolVersion = rhs.mProtocolVersion; 00063 mTransport = rhs.mTransport; 00064 mSentHost = rhs.mSentHost; 00065 mSentPort = rhs.mSentPort; 00066 } 00067 return *this; 00068 } 00069 00070 ParserCategory * 00071 Via::clone() const 00072 { 00073 return new Via(*this); 00074 } 00075 00076 ParserCategory * 00077 Via::clone(void* location) const 00078 { 00079 return new (location) Via(*this); 00080 } 00081 00082 ParserCategory* 00083 Via::clone(PoolBase* pool) const 00084 { 00085 return new (pool) Via(*this, pool); 00086 } 00087 00088 Data& 00089 Via::protocolName() 00090 { 00091 checkParsed(); 00092 return mProtocolName; 00093 } 00094 00095 const Data& 00096 Via::protocolName() const 00097 { 00098 checkParsed(); 00099 return mProtocolName; 00100 } 00101 00102 Data& 00103 Via::protocolVersion() 00104 { 00105 checkParsed(); 00106 return mProtocolVersion; 00107 } 00108 00109 const Data& 00110 Via::protocolVersion() const 00111 { 00112 checkParsed(); 00113 return mProtocolVersion; 00114 } 00115 00116 Data& Via:: 00117 transport() 00118 { 00119 checkParsed(); 00120 return mTransport; 00121 } 00122 00123 const Data& Via:: 00124 transport() const 00125 { 00126 checkParsed(); 00127 return mTransport; 00128 } 00129 00130 Data& 00131 Via::sentHost() 00132 { 00133 checkParsed(); 00134 return mSentHost; 00135 } 00136 00137 const Data& 00138 Via::sentHost() const 00139 { 00140 checkParsed(); 00141 return mSentHost; 00142 } 00143 00144 int& 00145 Via::sentPort() 00146 { 00147 checkParsed(); 00148 return mSentPort; 00149 } 00150 00151 int 00152 Via::sentPort() const 00153 { 00154 checkParsed(); 00155 return mSentPort; 00156 } 00157 00158 void 00159 Via::parse(ParseBuffer& pb) 00160 { 00161 const char* startMark; 00162 startMark = pb.skipWhitespace(); 00163 static std::bitset<256> wos=Data::toBitset("\r\n\t /"); 00164 pb.skipToOneOf(wos); 00165 pb.data(mProtocolName, startMark); 00166 pb.skipToChar('/'); 00167 pb.skipChar(); 00168 startMark = pb.skipWhitespace(); 00169 pb.skipToOneOf(wos); 00170 pb.data(mProtocolVersion, startMark); 00171 00172 pb.skipToChar('/'); 00173 pb.skipChar(); 00174 startMark = pb.skipWhitespace(); 00175 00176 // !jf! this should really be skipTokenChar() since for instance, if the 00177 // protocol token is missing it will read the rest of the Via into this field 00178 pb.skipNonWhitespace(); 00179 pb.data(mTransport, startMark); 00180 00181 startMark = pb.skipWhitespace(); 00182 pb.assertNotEof(); 00183 if (*startMark == '[') 00184 { 00185 startMark = pb.skipChar(); 00186 pb.skipToChar(']'); 00187 pb.data(mSentHost, startMark); 00188 // .bwc. We do not save this canonicalization, since we weren't doing so 00189 // before. This may change soon. 00190 Data canonicalizedHost=DnsUtil::canonicalizeIpV6Address(mSentHost); 00191 if(canonicalizedHost.empty()) 00192 { 00193 // .bwc. So the V6 addy is garbage. 00194 throw ParseException("Unparsable V6 address (note, this might" 00195 " be unparsable because IPV6 support is not" 00196 " enabled)", "Via", 00197 __FILE__, 00198 __LINE__); 00199 } 00200 pb.skipChar(); 00201 } 00202 else 00203 { 00204 // .bwc. If we hit whitespace, we have the host. 00205 static std::bitset<256> delimiter=Data::toBitset(";: \t\r\n"); 00206 pb.skipToOneOf(delimiter); 00207 pb.data(mSentHost, startMark); 00208 } 00209 00210 pb.skipToOneOf(";:"); 00211 00212 if (!pb.eof() && *pb.position() == ':') 00213 { 00214 startMark = pb.skipChar(':'); 00215 mSentPort = pb.integer(); 00216 static std::bitset<256> delimiter=Data::toBitset("; \t\r\n"); 00217 pb.skipToOneOf(delimiter); 00218 } 00219 else 00220 { 00221 mSentPort = 0; 00222 } 00223 parseParameters(pb); 00224 } 00225 00226 EncodeStream& 00227 Via::encodeParsed(EncodeStream& str) const 00228 { 00229 str << mProtocolName << Symbols::SLASH << mProtocolVersion << Symbols::SLASH << mTransport 00230 << Symbols::SPACE; 00231 00232 if (DnsUtil::isIpV6Address(mSentHost)) 00233 { 00234 str << '[' << mSentHost << ']'; 00235 } 00236 else 00237 { 00238 str << mSentHost; 00239 } 00240 00241 if (mSentPort != 0) 00242 { 00243 str << Symbols::COLON << mSentPort; 00244 } 00245 encodeParameters(str); 00246 return str; 00247 } 00248 00249 ParameterTypes::Factory Via::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; 00250 00251 Parameter* 00252 Via::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) 00253 { 00254 if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) 00255 { 00256 return ParameterFactories[type](type, pb, terminators, pool); 00257 } 00258 return 0; 00259 } 00260 00261 bool 00262 Via::exists(const Param<Via>& paramType) const 00263 { 00264 checkParsed(); 00265 bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; 00266 return ret; 00267 } 00268 00269 void 00270 Via::remove(const Param<Via>& paramType) 00271 { 00272 checkParsed(); 00273 removeParameterByEnum(paramType.getTypeNum()); 00274 } 00275 00276 #define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ 00277 _enum##_Param::DType& \ 00278 Via::param(const _enum##_Param& paramType) \ 00279 { \ 00280 checkParsed(); \ 00281 _enum##_Param::Type* p = \ 00282 static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ 00283 if (!p) \ 00284 { \ 00285 p = new _enum##_Param::Type(paramType.getTypeNum()); \ 00286 mParameters.push_back(p); \ 00287 } \ 00288 return p->value(); \ 00289 } \ 00290 \ 00291 const _enum##_Param::DType& \ 00292 Via::param(const _enum##_Param& paramType) const \ 00293 { \ 00294 checkParsed(); \ 00295 _enum##_Param::Type* p = \ 00296 static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ 00297 if (!p) \ 00298 { \ 00299 InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ 00300 DebugLog(<< *this); \ 00301 throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ 00302 } \ 00303 return p->value(); \ 00304 } 00305 00306 defineParam(branch, "branch", BranchParameter, "RFC 3261"); 00307 defineParam(comp, "comp", DataParameter, "RFC 3486"); 00308 defineParam(received, "received", DataParameter, "RFC 3261"); 00309 defineParam(rport, "rport", RportParameter, "RFC 3581"); 00310 defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261"); 00311 defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049"); 00312 defineParam(maddr, "maddr", DataParameter, "RFC 3261"); 00313 00314 #undef defineParam 00315 00316 /* ==================================================================== 00317 * The Vovida Software License, Version 1.0 00318 * 00319 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00320 * 00321 * Redistribution and use in source and binary forms, with or without 00322 * modification, are permitted provided that the following conditions 00323 * are met: 00324 * 00325 * 1. Redistributions of source code must retain the above copyright 00326 * notice, this list of conditions and the following disclaimer. 00327 * 00328 * 2. Redistributions in binary form must reproduce the above copyright 00329 * notice, this list of conditions and the following disclaimer in 00330 * the documentation and/or other materials provided with the 00331 * distribution. 00332 * 00333 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00334 * and "Vovida Open Communication Application Library (VOCAL)" must 00335 * not be used to endorse or promote products derived from this 00336 * software without prior written permission. For written 00337 * permission, please contact vocal@vovida.org. 00338 * 00339 * 4. Products derived from this software may not be called "VOCAL", nor 00340 * may "VOCAL" appear in their name, without prior written 00341 * permission of Vovida Networks, Inc. 00342 * 00343 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00344 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00345 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00346 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00347 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00348 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00349 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00350 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00351 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00352 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00353 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00354 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00355 * DAMAGE. 00356 * 00357 * ==================================================================== 00358 * 00359 * This software consists of voluntary contributions made by Vovida 00360 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00361 * Inc. For more information on Vovida Networks, Inc., please see 00362 * <http://www.vovida.org/>. 00363 * 00364 */
1.7.5.1