123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- //
- // Copyright (C) 2004 Andras Varga
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public License
- // as published by the Free Software Foundation; either version 2
- // of the License, or (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- //
- #include "TCPTester.h"
- #include "inet/networklayer/contract/NetworkProtocolCommand_m.h"
- #include "inet/networklayer/common/IPSocket.h"
- #include "inet/networklayer/contract/ipv4/IPv4ControlInfo.h"
- namespace inet {
- namespace tcp {
- TCPTesterBase::TCPTesterBase() : cSimpleModule()
- {
- }
- void TCPTesterBase::initialize()
- {
- fromASeq = 0;
- fromBSeq = 0;
- tcpdump.setOutStream(EVSTREAM);
- }
- void TCPTesterBase::dump(TCPSegment *seg, bool fromA, const char *comment)
- {
- #if OMNETPP_VERSION < 0x0500
- if (getEnvir()->isDisabled())
- return;
- #else
- if (getEnvir()->isExpressMode())
- return;
- #endif
- char lbl[32];
- sprintf(lbl," %c%03d", fromA ? 'A' : 'B', fromA ? fromASeq : fromBSeq);
- std::ostringstream out;
- tcpdump.setOutStream(out);
- tcpdump.tcpDump(fromA, lbl, seg, std::string(fromA?"A":"B"),std::string(fromA?"B":"A"), comment);
- EV_DEBUG_C("testing") << out.str();
- tcpdump.setOutStream(EVSTREAM);
- }
- void TCPTesterBase::finish()
- {
- char buf[128];
- sprintf(buf,"tcpdump finished, A:%d B:%d segments",fromASeq,fromBSeq);
- std::ostringstream out;
- tcpdump.setOutStream(out);
- tcpdump.dump("", buf);
- EV_DEBUG_C("testing") << out.str();
- tcpdump.setOutStream(EVSTREAM);
- }
- //---
- Define_Module(TCPScriptableTester);
- void TCPScriptableTester::initialize()
- {
- TCPTesterBase::initialize();
- const char *script = par("script");
- parseScript(script);
- }
- void TCPScriptableTester::parseScript(const char *script)
- {
- const char *s = script;
- while (*s)
- {
- Command cmd;
- // direction
- while (isspace(*s)) s++;
- if (*s=='a' || *s=='A')
- cmd.fromA = true;
- else if (*s=='b' || *s=='B')
- cmd.fromA = false;
- else
- throw cRuntimeError("syntax error in script: wrong segment spec");
- s++;
- // seg number
- if (!isdigit(*s))
- throw cRuntimeError("syntax error in script: wrong segment spec");
- cmd.segno = atoi(s);
- while (isdigit(*s)) s++;
- // command
- while (isspace(*s)) s++;
- if (!strncmp(s,"delete",6)) {
- cmd.command = CMD_DELETE; s+=6;
- } else if (!strncmp(s,"delay",5)) {
- cmd.command = CMD_COPY; s+=5;
- } else if (!strncmp(s,"copy",4)) {
- cmd.command = CMD_COPY; s+=4;
- } else
- throw cRuntimeError("syntax error in script: wrong command");
- // args
- if (cmd.command==CMD_COPY)
- {
- for (;;)
- {
- while (isspace(*s)) s++;
- if (!*s || *s==';') break;
- double d = strtod(s,&const_cast<char *&>(s));
- cmd.delays.push_back(d);
- while (isspace(*s)) s++;
- if (!*s || *s==';') break;
- if (*s!=',')
- throw cRuntimeError("syntax error in script: error in arg list");
- s++;
- }
- }
- // add command
- commands.push_back(cmd);
- // skip delimiter
- while (isspace(*s)) s++;
- if (!*s) break;
- if (*s!=';')
- throw cRuntimeError("syntax error in script: command separator ';' missing");
- s++;
- while (isspace(*s)) s++;
- }
- }
- void TCPScriptableTester::handleMessage(cMessage *msg)
- {
- if (dynamic_cast<RegisterTransportProtocolCommand*>(msg))
- {
- delete msg;
- return;
- }
- if (msg->isSelfMessage())
- {
- TCPSegment *seg = check_and_cast<TCPSegment *>(msg);
- dispatchSegment(seg);
- }
- else if (msg->isPacket())
- {
- TCPSegment *seg = check_and_cast<TCPSegment *>(msg);
- bool fromA = msg->arrivedOn("in1");
- processIncomingSegment(seg, fromA);
- }
- else if (dynamic_cast<IPRegisterProtocolCommand *>(msg)) {
- delete msg;
- }
- else
- {
- throw cRuntimeError("Unknown message");
- }
- }
- void TCPScriptableTester::dispatchSegment(TCPSegment *seg)
- {
- Command *cmd = (Command *)seg->getContextPointer();
- bool fromA = cmd->fromA;
- bubble("introducing copy");
- dump(seg, fromA, "introducing copy");
- send(seg, fromA ? "out2" : "out1");
- }
- void TCPScriptableTester::processIncomingSegment(TCPSegment *seg, bool fromA)
- {
- int segno = fromA ? ++fromASeq : ++fromBSeq;
- // find entry in script
- Command *cmd = NULL;
- for (CommandVector::iterator i=commands.begin(); i!=commands.end(); ++i)
- if (i->fromA==fromA && i->segno==segno)
- cmd = &(*i);
- if (!cmd)
- {
- // dump & forward
- dump(seg, fromA);
- send(seg, fromA ? "out2" : "out1");
- }
- else if (cmd->command==CMD_DELETE)
- {
- bubble("deleting");
- dump(seg, fromA, "deleting");
- delete seg;
- }
- else if (cmd->command==CMD_COPY)
- {
- bubble("removing original");
- dump(seg, fromA, "removing original");
- for (unsigned int i=0; i<cmd->delays.size(); i++)
- {
- simtime_t d = cmd->delays[i];
- TCPSegment *segcopy = (TCPSegment *)seg->dup();
- segcopy->setControlInfo(new IPv4ControlInfo(*check_and_cast<IPv4ControlInfo *>(seg->getControlInfo())));
- if (d==0)
- {
- bubble("forwarding after 0 delay");
- dump(segcopy, fromA, "introducing copy");
- send(segcopy, fromA ? "out2" : "out1");
- }
- else
- {
- segcopy->setContextPointer(cmd);
- scheduleAt(simTime()+d, segcopy);
- }
- }
- delete seg;
- }
- else
- {
- throw cRuntimeError("wrong command code");
- }
- }
- //------
- Define_Module(TCPRandomTester);
- void TCPRandomTester::initialize()
- {
- TCPTesterBase::initialize();
- pdelete = par("pdelete");
- pdelay = par("pdelay");
- pcopy = par("pcopy");
- numCopies = &par("numCopies");
- delay = &par("delayValue");
- }
- void TCPRandomTester::handleMessage(cMessage *msg)
- {
- if (dynamic_cast<RegisterTransportProtocolCommand*>(msg))
- {
- delete msg;
- return;
- }
- if (msg->isSelfMessage())
- {
- TCPSegment *seg = check_and_cast<TCPSegment *>(msg);
- dispatchSegment(seg);
- }
- else if (msg->isPacket())
- {
- TCPSegment *seg = check_and_cast<TCPSegment *>(msg);
- bool fromA = msg->arrivedOn("in1");
- processIncomingSegment(seg, fromA);
- }
- else if (dynamic_cast<IPRegisterProtocolCommand *>(msg)) {
- delete msg;
- }
- else
- {
- throw cRuntimeError("Unknown message");
- }
- }
- void TCPRandomTester::dispatchSegment(TCPSegment *seg)
- {
- bool fromA = (bool)seg->getContextPointer();
- bubble("introducing copy");
- dump(seg, fromA, "introducing copy");
- send(seg, fromA ? "out2" : "out1");
- }
- void TCPRandomTester::processIncomingSegment(TCPSegment *seg, bool fromA)
- {
- if (fromA) ++fromASeq; else ++fromBSeq;
- // decide what to do
- double x = dblrand();
- if (x<=pdelete)
- {
- bubble("deleting");
- dump(seg, fromA, "deleting");
- delete seg;
- }
- else if (x-=pdelete, x<=pdelay)
- {
- bubble("delay: removing original");
- dump(seg, fromA, "delay: removing original");
- double d = delay->doubleValue();
- seg->setContextPointer((void*)fromA);
- scheduleAt(simTime()+d, seg);
- }
- else if (x-=pdelay, x<=pcopy)
- {
- bubble("copy: removing original");
- dump(seg, fromA, "copy: removing original");
- int n = numCopies->longValue();
- for (int i=0; i<n; i++)
- {
- double d = delay->doubleValue();
- TCPSegment *segcopy = (TCPSegment *)seg->dup();
- segcopy->setControlInfo(new IPv4ControlInfo(*check_and_cast<IPv4ControlInfo *>(seg->getControlInfo())));
- segcopy->setContextPointer((void *)fromA);
- scheduleAt(simTime()+d, segcopy);
- }
- delete seg;
- }
- else
- {
- // dump & forward
- dump(seg, fromA);
- send(seg, fromA ? "out2" : "out1");
- }
- }
- } // namespace tcp
- } // namespace inet
|