|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #if defined (HAVE_POPT_H) 00006 #include <popt.h> 00007 #else 00008 #ifndef WIN32 00009 #warning "will not work very well without libpopt" 00010 #endif 00011 #endif 00012 00013 #include <signal.h> 00014 #include <iostream> 00015 00016 #include "resip/stack/TcpTransport.hxx" 00017 #include "resip/stack/Helper.hxx" 00018 #include "resip/stack/PlainContents.hxx" 00019 #include "resip/stack/SipMessage.hxx" 00020 #include "resip/stack/Uri.hxx" 00021 #include "resip/stack/ExtensionHeader.hxx" 00022 #include "rutil/Data.hxx" 00023 #include "rutil/DnsUtil.hxx" 00024 #include "rutil/Logger.hxx" 00025 #include "rutil/Random.hxx" 00026 #include "rutil/DataStream.hxx" 00027 00028 using namespace resip; 00029 using namespace std; 00030 00031 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00032 00033 int 00034 main(int argc, char* argv[]) 00035 { 00036 #ifndef _WIN32 00037 if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) 00038 { 00039 cerr << "Couldn't install signal handler for SIGPIPE" << endl; 00040 exit(-1); 00041 } 00042 #endif 00043 00044 #ifdef WIN32 00045 initNetwork(); 00046 #endif 00047 00048 char* logType = 0; 00049 const char* logLevel = "WARNING"; 00050 int runs = 100; 00051 int window = 10; 00052 int seltime = 100; 00053 00054 #if defined(HAVE_POPT_H) 00055 struct poptOption table[] = { 00056 {"log-type", 'l', POPT_ARG_STRING, &logType, 0, "where to send logging messages", "syslog|cerr|cout"}, 00057 {"log-level", 'v', POPT_ARG_STRING, &logLevel, 0, "specify the default log level", "DEBUG|INFO|WARNING|ALERT"}, 00058 {"num-runs", 'r', POPT_ARG_INT, &runs, 0, "number of calls in test", 0}, 00059 {"window-size", 'w', POPT_ARG_INT, &window, 0, "number of registrations in test", 0}, 00060 {"select-time", 's', POPT_ARG_INT, &seltime, 0, "number of runs in test", 0}, 00061 POPT_AUTOHELP 00062 { NULL, 0, 0, NULL, 0 } 00063 }; 00064 00065 poptContext context = poptGetContext(NULL, argc, const_cast<const char**>(argv), table, 0); 00066 poptGetNextOpt(context); 00067 poptFreeContext(context); 00068 #endif 00069 00070 #ifdef WIN32 00071 Log::initialize(Log::Cout, Log::Info, "testTcp"); 00072 #else 00073 Log::initialize(logType, logLevel, argv[0]); 00074 #endif 00075 00076 cout << "Performing " << runs << " runs." << endl; 00077 00078 Fifo<TransactionMessage> txFifo; 00079 TcpTransport* sender = new TcpTransport(txFifo, 5070, V4, Data::Empty); 00080 00081 Fifo<TransactionMessage> rxFifo; 00082 TcpTransport* receiver = new TcpTransport(rxFifo, 5080, V4, Data::Empty); 00083 00084 NameAddr target; 00085 target.uri().scheme() = "sip"; 00086 target.uri().user() = "fluffy"; 00087 target.uri().host() = "localhost"; 00088 target.uri().port() = 5080; 00089 target.uri().param(p_transport) = "tcp"; 00090 00091 NameAddr from = target; 00092 from.uri().port() = 5070; 00093 00094 InfoLog (<< "Creating messages"); 00095 00096 list<SipMessage*> messages; 00097 { 00098 UInt64 startTime = Timer::getTimeMs(); 00099 for (int i=0; i<runs; i++) 00100 { 00101 SipMessage* m = Helper::makeInvite( target, from, from); 00102 m->header(h_Vias).front().transport() = Tuple::toData(sender->transport()); 00103 m->header(h_Vias).front().sentHost() = "localhost"; 00104 m->header(h_Vias).front().sentPort() = sender->port(); 00105 int contentLength=resip::Random::getRandom()%65535; 00106 std::string body(contentLength,'0'); 00107 std::auto_ptr<Contents> contents(new PlainContents(Data(body.data(), body.size()))); 00108 m->setContents(contents); 00109 int headerLength=resip::Random::getRandom()%1024; 00110 std::string bigHeader(headerLength,'h'); 00111 m->header(h_Subject).value()=Data(bigHeader.data(), bigHeader.size()); 00112 messages.push_back(m); 00113 } 00114 00115 UInt64 elapsed = Timer::getTimeMs() - startTime; 00116 cout << runs << " calls performed in " << elapsed << " ms, a rate of " 00117 << runs / ((float) elapsed / 1000.0) << " calls per second.]" << endl; 00118 00119 InfoLog (<< "Messages created"); 00120 } 00121 00122 //delete receiver; 00123 //receiver=0; 00124 00125 in_addr in; 00126 DnsUtil::inet_pton("127.0.0.1", in); 00127 Tuple dest(in, target.uri().port(), TCP); 00128 InfoLog (<< "Sending to " << dest); 00129 00130 UInt64 startTime = Timer::getTimeMs(); 00131 00132 int tid=1; 00133 int outstanding=0; 00134 00135 while (!messages.empty()) 00136 { 00137 // load up the send window 00138 while (outstanding < window) 00139 { 00140 Data encoded; 00141 { 00142 DataStream strm(encoded); 00143 SipMessage* next = messages.front(); 00144 messages.pop_front(); 00145 next->encode(strm); 00146 outstanding++; 00147 delete next; 00148 } 00149 std::auto_ptr<SendData> toSend(sender->makeSendData(dest, encoded, Data(tid++), Data::Empty)); 00150 sender->send(toSend); 00151 } 00152 00153 FdSet fdset; 00154 if (receiver) receiver->buildFdSet(fdset); 00155 sender->buildFdSet(fdset); 00156 00157 fdset.selectMilliSeconds(seltime); 00158 00159 if (receiver) receiver->process(fdset); 00160 sender->process(fdset); 00161 00162 Message* msg; 00163 if (rxFifo.messageAvailable()) 00164 { 00165 msg = rxFifo.getNext(); 00166 SipMessage* received = dynamic_cast<SipMessage*>(msg); 00167 if (received) 00168 { 00169 //DebugLog (<< "got: " << received->brief()); 00170 outstanding--; 00171 00172 assert (received->header(h_RequestLine).uri().host() == "localhost"); 00173 assert (received->header(h_To).uri().host() == "localhost"); 00174 assert (received->header(h_From).uri().host() == "localhost"); 00175 assert (!received->header(h_Vias).begin()->sentHost().empty()); 00176 assert (received->header(h_Contacts).begin()->uri().host() == "localhost"); 00177 assert (!received->header(h_CallId).value().empty()); 00178 } 00179 delete msg; 00180 } 00181 } 00182 00183 while (outstanding>0) 00184 { 00185 FdSet fdset; 00186 if (receiver) receiver->buildFdSet(fdset); 00187 sender->buildFdSet(fdset); 00188 00189 fdset.selectMilliSeconds(seltime); 00190 00191 if (receiver) receiver->process(fdset); 00192 sender->process(fdset); 00193 00194 while (rxFifo.messageAvailable()) 00195 { 00196 Message* msg = rxFifo.getNext(); 00197 SipMessage* received = dynamic_cast<SipMessage*>(msg); 00198 if (received) 00199 { 00200 //DebugLog (<< "got: " << received->brief()); 00201 outstanding--; 00202 00203 assert (received->header(h_RequestLine).uri().host() == "localhost"); 00204 assert (received->header(h_To).uri().host() == "localhost"); 00205 assert (received->header(h_From).uri().host() == "localhost"); 00206 assert (!received->header(h_Vias).begin()->sentHost().empty()); 00207 assert (received->header(h_Contacts).begin()->uri().host() == "localhost"); 00208 assert (!received->header(h_CallId).value().empty()); 00209 } 00210 delete msg; 00211 } 00212 } 00213 00214 UInt64 elapsed = Timer::getTimeMs() - startTime; 00215 cout << runs << " calls peformed in " << elapsed << " ms, a rate of " 00216 << runs / ((float) elapsed / 1000.0) << " calls per second.]" << endl; 00217 00218 SipMessage::checkContentLength=false; 00219 list<SipMessage*> garbage; 00220 { 00221 UInt64 startTime = Timer::getTimeMs(); 00222 for (int i=0; i<runs; i++) 00223 { 00224 SipMessage* m = Helper::makeInvite( target, from, from); 00225 m->header(h_Vias).front().transport() = Tuple::toData(sender->transport()); 00226 m->header(h_Vias).front().sentHost() = "localhost"; 00227 m->header(h_Vias).front().sentPort() = sender->port(); 00228 00229 garbage.push_back(m); 00230 } 00231 00232 UInt64 elapsed = Timer::getTimeMs() - startTime; 00233 cout << runs << " calls performed in " << elapsed << " ms, a rate of " 00234 << runs / ((float) elapsed / 1000.0) << " calls per second.]" << endl; 00235 00236 InfoLog (<< "Messages created"); 00237 } 00238 00239 int type=0; 00240 Data badContentLength1("-1"); 00241 Data badContentLength2("999999999999999999999999999999"); 00242 std::string hugeString(4096,'h'); 00243 ExtensionHeader h_huge(Data::from(hugeString)); 00244 00245 while (!garbage.empty()) 00246 { 00247 Data encoded; 00248 00249 switch(type%4) 00250 { 00251 case 0: 00252 case 1: 00253 { 00254 // .bwc. Send one at a time for maximum potential damage. 00255 { 00256 DataStream strm(encoded); 00257 SipMessage* next = garbage.front(); 00258 garbage.pop_front(); 00259 // .bwc. encodeSipFrag doesn't encode Content-Length if there is no 00260 // body; allowing us to add a bad one without conflicting. 00261 next->encodeSipFrag(strm); 00262 outstanding++; 00263 delete next; 00264 } 00265 00266 encoded.replace("\r\n\r\n","\r\nContent-Length: "+( type ? badContentLength1 : badContentLength2)+"\r\n\r\n"); 00267 } 00268 break; 00269 case 2: 00270 { 00271 DataStream strm(encoded); 00272 SipMessage* next = garbage.front(); 00273 garbage.pop_front(); 00274 next->header(h_Subject).value()=Data(hugeString.data(), hugeString.size()); 00275 next->encode(strm); 00276 delete next; 00277 } 00278 break; 00279 case 3: 00280 { 00281 DataStream strm(encoded); 00282 SipMessage* next = garbage.front(); 00283 garbage.pop_front(); 00284 next->header(h_huge).push_front(StringCategory("foo")); 00285 next->encode(strm); 00286 delete next; 00287 } 00288 break; 00289 } 00290 00291 ++type; 00292 std::auto_ptr<SendData> toSend(sender->makeSendData(dest, encoded, Data(tid++), Data::Empty)); 00293 sender->send(toSend); 00294 00295 FdSet fdset; 00296 if (receiver) receiver->buildFdSet(fdset); 00297 sender->buildFdSet(fdset); 00298 00299 fdset.selectMilliSeconds(seltime); 00300 00301 try 00302 { 00303 if (receiver) receiver->process(fdset); 00304 } 00305 catch(std::exception& e) 00306 { 00307 // .bwc. Do nothing substantive, since the stack thread doesn't 00308 } 00309 sender->process(fdset); 00310 00311 Message* msg; 00312 while (rxFifo.messageAvailable()) 00313 { 00314 msg = rxFifo.getNext(); 00315 SipMessage* received = dynamic_cast<SipMessage*>(msg); 00316 // .bwc. These are all unrecoverable garbage, we should not get 00317 // any sip traffic on this fifo. 00318 assert(!received); 00319 delete msg; 00320 } 00321 } 00322 00323 return 0; 00324 } 00325 00326 /* ==================================================================== 00327 * The Vovida Software License, Version 1.0 00328 * 00329 * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. 00330 * 00331 * Redistribution and use in source and binary forms, with or without 00332 * modification, are permitted provided that the following conditions 00333 * are met: 00334 * 00335 * 1. Redistributions of source code must retain the above copyright 00336 * notice, this list of conditions and the following disclaimer. 00337 * 00338 * 2. Redistributions in binary form must reproduce the above copyright 00339 * notice, this list of conditions and the following disclaimer in 00340 * the documentation and/or other materials provided with the 00341 * distribution. 00342 * 00343 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00344 * and "Vovida Open Communication Application Library (VOCAL)" must 00345 * not be used to endorse or promote products derived from this 00346 * software without prior written permission. For written 00347 * permission, please contact vocal@vovida.org. 00348 * 00349 * 4. Products derived from this software may not be called "VOCAL", nor 00350 * may "VOCAL" appear in their name, without prior written 00351 * permission of Vovida Networks, Inc. 00352 * 00353 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00354 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00355 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00356 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00357 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00358 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00359 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00360 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00361 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00362 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00363 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00364 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00365 * DAMAGE. 00366 * 00367 * ==================================================================== 00368 * 00369 * This software consists of voluntary contributions made by Vovida 00370 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00371 * Inc. For more information on Vovida Networks, Inc., please see 00372 * <http://www.vovida.org/>. 00373 * 00374 */
1.7.5.1