#include <SimpleTCP.h>
Public Member Functions | |
| SimpleTCPConnection () | |
| SimpleTCPConnection (TCP *mod, int appGateIndex, int connId) | |
| virtual void | sendToIP (TCPSegment *tcpseg) |
| Utility: adds control info to segment and sends it to the destination node. | |
| void | sendRst (uint32 seq, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort) |
| Utility: sends RST; does not use connection state. | |
| void | sendRstAck (uint32 seq, uint32 ack, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort) |
| Utility: sends RST+ACK; does not use connection state. | |
Static Public Attributes | |
| static StatisticsAndDelay | sad |
Protected Member Functions | |
| virtual void | sendToIP (TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest) |
| Utility: send IP packet to destination node. | |
| SimpleTCPConnection * | cloneListeningConnection () |
| Utility: clone a listening connection. | |
Definition at line 73 of file SimpleTCP.h.
| SimpleTCPConnection::SimpleTCPConnection | ( | ) | [inline] |
Definition at line 76 of file SimpleTCP.h.
Referenced by cloneListeningConnection().
:TCPConnection(){};
| SimpleTCPConnection::SimpleTCPConnection | ( | TCP * | mod, | |
| int | appGateIndex, | |||
| int | connId | |||
| ) | [inline] |
Definition at line 77 of file SimpleTCP.h.
:TCPConnection(mod, appGateIndex, connId){};
| SimpleTCPConnection * SimpleTCPConnection::cloneListeningConnection | ( | ) | [protected] |
Utility: clone a listening connection.
Used for forking.
Definition at line 248 of file SimpleTCP.cc.
{
SimpleTCPConnection *conn = new SimpleTCPConnection(tcpMain,appGateIndex,connId);
// following code to be kept consistent with initConnection()
const char *sendQueueClass = sendQueue->getClassName();
conn->sendQueue = check_and_cast<TCPSendQueue *>(createOne(sendQueueClass));
conn->sendQueue->setConnection(conn);
const char *receiveQueueClass = receiveQueue->getClassName();
conn->receiveQueue = check_and_cast<TCPReceiveQueue *>(createOne(receiveQueueClass));
conn->receiveQueue->setConnection(conn);
// create SACK retransmit queue
rexmitQueue = new TCPSACKRexmitQueue();
rexmitQueue->setConnection(this);
const char *tcpAlgorithmClass = tcpAlgorithm->getClassName();
conn->tcpAlgorithm = check_and_cast<TCPAlgorithm *>(createOne(tcpAlgorithmClass));
conn->tcpAlgorithm->setConnection(conn);
conn->state = conn->tcpAlgorithm->getStateVariables();
configureStateVariables();
conn->tcpAlgorithm->initialize();
// put it into LISTEN, with our localAddr/localPort
conn->state->active = false;
conn->state->fork = true;
conn->localAddr = localAddr;
conn->localPort = localPort;
FSM_Goto(conn->fsm, TCP_S_LISTEN);
return conn;
}
| void SimpleTCPConnection::sendRst | ( | uint32 | seq, | |
| IPvXAddress | src, | |||
| IPvXAddress | dest, | |||
| int | srcPort, | |||
| int | destPort | |||
| ) |
Utility: sends RST; does not use connection state.
Definition at line 284 of file SimpleTCP.cc.
{
TCPSegment *tcpseg = createTCPSegment("RST");
tcpseg->setSrcPort(srcPort);
tcpseg->setDestPort(destPort);
tcpseg->setRstBit(true);
tcpseg->setSequenceNo(seq);
// send it
SimpleTCPConnection::sendToIP(tcpseg, src, dest);
}
| void SimpleTCPConnection::sendRstAck | ( | uint32 | seq, | |
| uint32 | ack, | |||
| IPvXAddress | src, | |||
| IPvXAddress | dest, | |||
| int | srcPort, | |||
| int | destPort | |||
| ) |
Utility: sends RST+ACK; does not use connection state.
Definition at line 298 of file SimpleTCP.cc.
{
TCPSegment *tcpseg = createTCPSegment("RST+ACK");
tcpseg->setSrcPort(srcPort);
tcpseg->setDestPort(destPort);
tcpseg->setRstBit(true);
tcpseg->setAckBit(true);
tcpseg->setSequenceNo(seq);
tcpseg->setAckNo(ack);
// send it
SimpleTCPConnection::sendToIP(tcpseg, src, dest);
}
| void SimpleTCPConnection::sendToIP | ( | TCPSegment * | tcpseg, | |
| IPvXAddress | src, | |||
| IPvXAddress | dest | |||
| ) | [protected, virtual] |
Utility: send IP packet to destination node.
Definition at line 454 of file SimpleTCP.cc.
{
/* main modifications for SimpleTCP start here */
StatisticsAndDelay& sad = dynamic_cast<SimpleTCP*>(tcpMain)->sad;
SimpleInfo* info = dynamic_cast<SimpleInfo*>(sad.globalNodeList->getPeerInfo(dest));
sad.numSent++;
if (info == NULL) {
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " No route to host " << dest
<< endl;
delete tcpseg;
sad.numDestUnavailableLost++;
return;
}
SimpleNodeEntry* destEntry = info->getEntry();
// calculate delay
simtime_t totalDelay = 0;
if (src != dest) {
SimpleNodeEntry::SimpleDelay temp;
if (sad.faultyDelay) {
SimpleInfo* thisInfo = static_cast<SimpleInfo*>(sad.globalNodeList->getPeerInfo(src));
temp = sad.nodeEntry->calcDelay(tcpseg, *destEntry,
!(thisInfo->getNpsLayer() == 0 ||
info->getNpsLayer() == 0)); //TODO
} else {
temp = sad.nodeEntry->calcDelay(tcpseg, *destEntry);
}
if (sad.useCoordinateBasedDelay == false) {
totalDelay = sad.constantDelay;
} else if (temp.second == false) {
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " Send queue full: packet " << tcpseg << " dropped"
<< endl;
delete tcpseg;
sad.numQueueLost++;
return;
} else {
totalDelay = temp.first;
}
}
SimpleInfo* thisInfo = dynamic_cast<SimpleInfo*>(sad.globalNodeList->getPeerInfo(src));
if (!sad.globalNodeList->areNodeTypesConnected(thisInfo->getTypeID(), info->getTypeID())) {
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " Partition " << thisInfo->getTypeID() << "->" << info->getTypeID()
<< " is not connected"
<< endl;
delete tcpseg;
sad.numPartitionLost++;
return;
}
if (sad.jitter) {
// jitter
//totalDelay += truncnormal(0, SIMTIME_DBL(totalDelay) * jitter);
//workaround (bug in truncnormal(): sometimes returns inf)
double temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.jitter);
while (temp == INFINITY || temp != temp) { // reroll if temp is INF or NaN
std::cerr << "\n******* SimpleTCPConnection: truncnormal() -> inf !!\n"
<< std::endl;
temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.jitter);
}
totalDelay += temp;
}
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " Packet " << tcpseg << " sent with delay = " << totalDelay
<< endl;
//RECORD_STATS(globalStatistics->addStdDev("SimpleTCP: delay", totalDelay));
/* main modifications for SimpleTCP end here */
tcpEV << "Sending: ";
printSegmentBrief(tcpseg);
if (!dest.isIPv6())
{
// send over IPv4
IPControlInfo *controlInfo = new IPControlInfo();
controlInfo->setProtocol(IP_PROT_TCP);
controlInfo->setSrcAddr(src.get4());
controlInfo->setDestAddr(dest.get4());
tcpseg->setControlInfo(controlInfo);
check_and_cast<TCP *>(simulation.getContextModule())->sendDirect(tcpseg, totalDelay, 0, destEntry->getTcpIPv4Gate());
}
else
{
// send over IPv6
IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
controlInfo->setProtocol(IP_PROT_TCP);
controlInfo->setSrcAddr(src.get6());
controlInfo->setDestAddr(dest.get6());
tcpseg->setControlInfo(controlInfo);
check_and_cast<TCP *>(simulation.getContextModule())->sendDirect(tcpseg, totalDelay, 0, destEntry->getTcpIPv6Gate());
}
}
| void SimpleTCPConnection::sendToIP | ( | TCPSegment * | tcpseg | ) | [virtual] |
Utility: adds control info to segment and sends it to the destination node.
Definition at line 314 of file SimpleTCP.cc.
Referenced by sendRst(), and sendRstAck().
{
StatisticsAndDelay& sad = dynamic_cast<SimpleTCP*>(tcpMain)->sad;
// record seq (only if we do send data) and ackno
if (sndNxtVector && tcpseg->getPayloadLength()!=0)
sndNxtVector->record(tcpseg->getSequenceNo());
if (sndAckVector)
sndAckVector->record(tcpseg->getAckNo());
// final touches on the segment before sending
tcpseg->setSrcPort(localPort);
tcpseg->setDestPort(remotePort);
ASSERT(tcpseg->getHeaderLength() >= TCP_HEADER_OCTETS); // TCP_HEADER_OCTETS = 20 (without options)
ASSERT(tcpseg->getHeaderLength() <= TCP_MAX_HEADER_OCTETS); // TCP_MAX_HEADER_OCTETS = 60
// add header byte length for the skipped IP header
int ipHeaderBytes = 0;
if (remoteAddr.isIPv6()) {
ipHeaderBytes = IPv6_HEADER_BYTES;
} else {
ipHeaderBytes = IP_HEADER_BYTES;
}
tcpseg->setByteLength(tcpseg->getHeaderLength() +
tcpseg->getPayloadLength() + ipHeaderBytes);
tcpEV << "Sending: ";
printSegmentBrief(tcpseg);
// TBD reuse next function for sending
/* main modifications for SimpleTCP start here */
const IPvXAddress& src = IPAddressResolver().addressOf(tcpMain->getParentModule());
//const IPvXAddress& src = localAddr;
const IPvXAddress& dest = remoteAddr;
SimpleInfo* info = dynamic_cast<SimpleInfo*>(sad.globalNodeList->getPeerInfo(dest));
sad.numSent++;
if (info == NULL) {
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " No route to host " << dest
<< endl;
delete tcpseg;
sad.numDestUnavailableLost++;
return;
}
SimpleNodeEntry* destEntry = info->getEntry();
// calculate delay
simtime_t totalDelay = 0;
if (src != dest) {
SimpleNodeEntry::SimpleDelay temp;
if (sad.faultyDelay) {
SimpleInfo* thisInfo = static_cast<SimpleInfo*>(sad.globalNodeList->getPeerInfo(src));
temp = sad.nodeEntry->calcDelay(tcpseg, *destEntry,
!(thisInfo->getNpsLayer() == 0 ||
info->getNpsLayer() == 0)); //TODO
} else {
temp = sad.nodeEntry->calcDelay(tcpseg, *destEntry);
}
if (sad.useCoordinateBasedDelay == false) {
totalDelay = sad.constantDelay;
} else if (temp.second == false) {
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " Send queue full: packet " << tcpseg << " dropped"
<< endl;
delete tcpseg;
sad.numQueueLost++;
return;
} else {
totalDelay = temp.first;
}
}
SimpleInfo* thisInfo = dynamic_cast<SimpleInfo*>(sad.globalNodeList->getPeerInfo(src));
if (!sad.globalNodeList->areNodeTypesConnected(thisInfo->getTypeID(), info->getTypeID())) {
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " Partition " << thisInfo->getTypeID() << "->" << info->getTypeID()
<< " is not connected"
<< endl;
delete tcpseg;
sad.numPartitionLost++;
return;
}
if (sad.jitter) {
// jitter
//totalDelay += truncnormal(0, SIMTIME_DBL(totalDelay) * jitter);
//workaround (bug in truncnormal(): sometimes returns inf)
double temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.jitter);
while (temp == INFINITY || temp != temp) { // reroll if temp is INF or NaN
std::cerr << "\n******* SimpleTCPConnection: truncnormal() -> inf !!\n"
<< std::endl;
temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.jitter);
}
totalDelay += temp;
}
EV << "[SimpleTCPConnection::sendToIP() @ " << src << "]\n"
<< " Packet " << tcpseg << " sent with delay = " << totalDelay
<< endl;
//RECORD_STATS(globalStatistics->addStdDev("SimpleTCP: delay", totalDelay));
/* main modifications for SimpleTCP end here */
if (!remoteAddr.isIPv6())
{
// send over IPv4
IPControlInfo *controlInfo = new IPControlInfo();
controlInfo->setProtocol(IP_PROT_TCP);
controlInfo->setSrcAddr(src.get4());
controlInfo->setDestAddr(dest.get4());
tcpseg->setControlInfo(controlInfo);
tcpMain->sendDirect(tcpseg, totalDelay, 0, destEntry->getTcpIPv4Gate());
}
else
{
// send over IPv6
IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
controlInfo->setProtocol(IP_PROT_TCP);
controlInfo->setSrcAddr(src.get6());
controlInfo->setDestAddr(dest.get6());
tcpseg->setControlInfo(controlInfo);
tcpMain->sendDirect(tcpseg, totalDelay, 0, destEntry->getTcpIPv6Gate());
}
}
Definition at line 82 of file SimpleTCP.h.
Referenced by sendToIP().
1.7.1