Public Member Functions | Static Public Attributes | Protected Member Functions

SimpleTCPConnection Class Reference

#include <SimpleTCP.h>

List of all members.

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.
SimpleTCPConnectioncloneListeningConnection ()
 Utility: clone a listening connection.

Detailed Description

Definition at line 73 of file SimpleTCP.h.


Constructor & Destructor Documentation

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){};


Member Function Documentation

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());
    }
}


Member Data Documentation

Definition at line 82 of file SimpleTCP.h.

Referenced by sendToIP().


The documentation for this class was generated from the following files: