|
reSIProcate/stack
9694
|
#include <signal.h>#include <iostream>#include "resip/stack/TcpTransport.hxx"#include "resip/stack/Helper.hxx"#include "resip/stack/PlainContents.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/stack/Uri.hxx"#include "resip/stack/ExtensionHeader.hxx"#include "rutil/Data.hxx"#include "rutil/DnsUtil.hxx"#include "rutil/Logger.hxx"#include "rutil/Random.hxx"#include "rutil/DataStream.hxx"
Go to the source code of this file.
Defines | |
| #define | RESIPROCATE_SUBSYSTEM Subsystem::SIP |
Functions | |
| int | main (int argc, char *argv[]) |
| #define RESIPROCATE_SUBSYSTEM Subsystem::SIP |
Definition at line 31 of file testTcp.cxx.
| int main | ( | int | argc, |
| char * | argv[] | ||
| ) |
Definition at line 34 of file testTcp.cxx.
References resip::TcpBaseTransport::buildFdSet(), resip::SipMessage::checkContentLength, context, resip::Log::Cout, dest, resip::Data::Empty, resip::SipMessage::encode(), resip::SipMessage::encodeSipFrag(), resip::Data::from(), resip::Fifo< Msg >::getNext(), resip::Random::getRandom(), resip::Timer::getTimeMs(), resip::SipMessage::header(), resip::Uri::host(), resip::DnsUtil::inet_pton(), resip::Log::Info, InfoLog, resip::Log::initialize(), resip::initNetwork(), resip::Helper::makeInvite(), resip::Transport::makeSendData(), resip::AbstractFifo< T >::messageAvailable(), resip::ParserCategory::param(), resip::Uri::port(), resip::Transport::port(), resip::TcpBaseTransport::process(), received, resip::Data::replace(), resip::Uri::scheme(), resip::FdSet::selectMilliSeconds(), resip::InternalTransport::send(), resip::SipMessage::setContents(), resip::TCP, resip::toData(), resip::TcpTransport::transport(), type, resip::RequestLine::uri(), resip::NameAddr::uri(), resip::Uri::user(), and resip::V4.
{
#ifndef _WIN32
if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR)
{
cerr << "Couldn't install signal handler for SIGPIPE" << endl;
exit(-1);
}
#endif
#ifdef WIN32
initNetwork();
#endif
char* logType = 0;
const char* logLevel = "WARNING";
int runs = 100;
int window = 10;
int seltime = 100;
#if defined(HAVE_POPT_H)
struct poptOption table[] = {
{"log-type", 'l', POPT_ARG_STRING, &logType, 0, "where to send logging messages", "syslog|cerr|cout"},
{"log-level", 'v', POPT_ARG_STRING, &logLevel, 0, "specify the default log level", "DEBUG|INFO|WARNING|ALERT"},
{"num-runs", 'r', POPT_ARG_INT, &runs, 0, "number of calls in test", 0},
{"window-size", 'w', POPT_ARG_INT, &window, 0, "number of registrations in test", 0},
{"select-time", 's', POPT_ARG_INT, &seltime, 0, "number of runs in test", 0},
POPT_AUTOHELP
{ NULL, 0, 0, NULL, 0 }
};
poptContext context = poptGetContext(NULL, argc, const_cast<const char**>(argv), table, 0);
poptGetNextOpt(context);
poptFreeContext(context);
#endif
#ifdef WIN32
Log::initialize(Log::Cout, Log::Info, "testTcp");
#else
Log::initialize(logType, logLevel, argv[0]);
#endif
cout << "Performing " << runs << " runs." << endl;
Fifo<TransactionMessage> txFifo;
TcpTransport* sender = new TcpTransport(txFifo, 5070, V4, Data::Empty);
Fifo<TransactionMessage> rxFifo;
TcpTransport* receiver = new TcpTransport(rxFifo, 5080, V4, Data::Empty);
NameAddr target;
target.uri().scheme() = "sip";
target.uri().user() = "fluffy";
target.uri().host() = "localhost";
target.uri().port() = 5080;
target.uri().param(p_transport) = "tcp";
NameAddr from = target;
from.uri().port() = 5070;
InfoLog (<< "Creating messages");
list<SipMessage*> messages;
{
UInt64 startTime = Timer::getTimeMs();
for (int i=0; i<runs; i++)
{
SipMessage* m = Helper::makeInvite( target, from, from);
m->header(h_Vias).front().transport() = Tuple::toData(sender->transport());
m->header(h_Vias).front().sentHost() = "localhost";
m->header(h_Vias).front().sentPort() = sender->port();
int contentLength=resip::Random::getRandom()%65535;
std::string body(contentLength,'0');
std::auto_ptr<Contents> contents(new PlainContents(Data(body.data(), body.size())));
m->setContents(contents);
int headerLength=resip::Random::getRandom()%1024;
std::string bigHeader(headerLength,'h');
m->header(h_Subject).value()=Data(bigHeader.data(), bigHeader.size());
messages.push_back(m);
}
UInt64 elapsed = Timer::getTimeMs() - startTime;
cout << runs << " calls performed in " << elapsed << " ms, a rate of "
<< runs / ((float) elapsed / 1000.0) << " calls per second.]" << endl;
InfoLog (<< "Messages created");
}
//delete receiver;
//receiver=0;
in_addr in;
DnsUtil::inet_pton("127.0.0.1", in);
Tuple dest(in, target.uri().port(), TCP);
InfoLog (<< "Sending to " << dest);
UInt64 startTime = Timer::getTimeMs();
int tid=1;
int outstanding=0;
while (!messages.empty())
{
// load up the send window
while (outstanding < window)
{
Data encoded;
{
DataStream strm(encoded);
SipMessage* next = messages.front();
messages.pop_front();
next->encode(strm);
outstanding++;
delete next;
}
std::auto_ptr<SendData> toSend(sender->makeSendData(dest, encoded, Data(tid++), Data::Empty));
sender->send(toSend);
}
FdSet fdset;
if (receiver) receiver->buildFdSet(fdset);
sender->buildFdSet(fdset);
fdset.selectMilliSeconds(seltime);
if (receiver) receiver->process(fdset);
sender->process(fdset);
Message* msg;
if (rxFifo.messageAvailable())
{
msg = rxFifo.getNext();
SipMessage* received = dynamic_cast<SipMessage*>(msg);
if (received)
{
//DebugLog (<< "got: " << received->brief());
outstanding--;
assert (received->header(h_RequestLine).uri().host() == "localhost");
assert (received->header(h_To).uri().host() == "localhost");
assert (received->header(h_From).uri().host() == "localhost");
assert (!received->header(h_Vias).begin()->sentHost().empty());
assert (received->header(h_Contacts).begin()->uri().host() == "localhost");
assert (!received->header(h_CallId).value().empty());
}
delete msg;
}
}
while (outstanding>0)
{
FdSet fdset;
if (receiver) receiver->buildFdSet(fdset);
sender->buildFdSet(fdset);
fdset.selectMilliSeconds(seltime);
if (receiver) receiver->process(fdset);
sender->process(fdset);
while (rxFifo.messageAvailable())
{
Message* msg = rxFifo.getNext();
SipMessage* received = dynamic_cast<SipMessage*>(msg);
if (received)
{
//DebugLog (<< "got: " << received->brief());
outstanding--;
assert (received->header(h_RequestLine).uri().host() == "localhost");
assert (received->header(h_To).uri().host() == "localhost");
assert (received->header(h_From).uri().host() == "localhost");
assert (!received->header(h_Vias).begin()->sentHost().empty());
assert (received->header(h_Contacts).begin()->uri().host() == "localhost");
assert (!received->header(h_CallId).value().empty());
}
delete msg;
}
}
UInt64 elapsed = Timer::getTimeMs() - startTime;
cout << runs << " calls peformed in " << elapsed << " ms, a rate of "
<< runs / ((float) elapsed / 1000.0) << " calls per second.]" << endl;
SipMessage::checkContentLength=false;
list<SipMessage*> garbage;
{
UInt64 startTime = Timer::getTimeMs();
for (int i=0; i<runs; i++)
{
SipMessage* m = Helper::makeInvite( target, from, from);
m->header(h_Vias).front().transport() = Tuple::toData(sender->transport());
m->header(h_Vias).front().sentHost() = "localhost";
m->header(h_Vias).front().sentPort() = sender->port();
garbage.push_back(m);
}
UInt64 elapsed = Timer::getTimeMs() - startTime;
cout << runs << " calls performed in " << elapsed << " ms, a rate of "
<< runs / ((float) elapsed / 1000.0) << " calls per second.]" << endl;
InfoLog (<< "Messages created");
}
int type=0;
Data badContentLength1("-1");
Data badContentLength2("999999999999999999999999999999");
std::string hugeString(4096,'h');
ExtensionHeader h_huge(Data::from(hugeString));
while (!garbage.empty())
{
Data encoded;
switch(type%4)
{
case 0:
case 1:
{
// .bwc. Send one at a time for maximum potential damage.
{
DataStream strm(encoded);
SipMessage* next = garbage.front();
garbage.pop_front();
// .bwc. encodeSipFrag doesn't encode Content-Length if there is no
// body; allowing us to add a bad one without conflicting.
next->encodeSipFrag(strm);
outstanding++;
delete next;
}
encoded.replace("\r\n\r\n","\r\nContent-Length: "+( type ? badContentLength1 : badContentLength2)+"\r\n\r\n");
}
break;
case 2:
{
DataStream strm(encoded);
SipMessage* next = garbage.front();
garbage.pop_front();
next->header(h_Subject).value()=Data(hugeString.data(), hugeString.size());
next->encode(strm);
delete next;
}
break;
case 3:
{
DataStream strm(encoded);
SipMessage* next = garbage.front();
garbage.pop_front();
next->header(h_huge).push_front(StringCategory("foo"));
next->encode(strm);
delete next;
}
break;
}
++type;
std::auto_ptr<SendData> toSend(sender->makeSendData(dest, encoded, Data(tid++), Data::Empty));
sender->send(toSend);
FdSet fdset;
if (receiver) receiver->buildFdSet(fdset);
sender->buildFdSet(fdset);
fdset.selectMilliSeconds(seltime);
try
{
if (receiver) receiver->process(fdset);
}
catch(std::exception& e)
{
// .bwc. Do nothing substantive, since the stack thread doesn't
}
sender->process(fdset);
Message* msg;
while (rxFifo.messageAvailable())
{
msg = rxFifo.getNext();
SipMessage* received = dynamic_cast<SipMessage*>(msg);
// .bwc. These are all unrecoverable garbage, we should not get
// any sip traffic on this fifo.
assert(!received);
delete msg;
}
}
return 0;
}

1.7.5.1