INET Framework for OMNeT++/OMNEST
TCPSACKRexmitQueue Class Reference

#include <TCPSACKRexmitQueue.h>

List of all members.

Classes

struct  Region

Public Types

typedef std::list< RegionRexmitQueue

Public Member Functions

 TCPSACKRexmitQueue ()
virtual ~TCPSACKRexmitQueue ()
virtual void setConnection (TCPConnection *_conn)
virtual void init (uint32 seqNum)
virtual std::string str () const
virtual void info ()
virtual uint32 getBufferStartSeq ()
virtual uint32 getBufferEndSeq ()
virtual void discardUpTo (uint32 seqNum)
virtual void enqueueSentData (uint32 fromSeqNum, uint32 toSeqNum)
virtual void setSackedBit (uint32 fromSeqNum, uint32 toSeqNum)
virtual bool getSackedBit (uint32 seqNum)
virtual uint32 getQueueLength ()
virtual uint32 getHighestSackedSeqNum ()
virtual uint32 getHighestRexmittedSeqNum ()
virtual uint32 checkRexmitQueueForSackedOrRexmittedSegments (uint32 fromSeq)
virtual void resetSackedBit ()
virtual void resetRexmittedBit ()
virtual uint32 getTotalAmountOfSackedBytes ()
virtual uint32 getAmountOfSackedBytes (uint32 seqNum)
virtual uint32 getNumOfDiscontiguousSacks (uint32 seqNum)

Public Attributes

TCPConnectionconn
RexmitQueue rexmitQueue
uint32 begin
uint32 end

Detailed Description

Retransmission data for SACK.


Member Typedef Documentation


Constructor & Destructor Documentation

TCPSACKRexmitQueue::TCPSACKRexmitQueue ( )

Ctor

{
    conn = NULL;
    begin = end = 0;
}
TCPSACKRexmitQueue::~TCPSACKRexmitQueue ( ) [virtual]

Virtual dtor.

{
    while (!rexmitQueue.empty())
        rexmitQueue.pop_front();
}

Member Function Documentation

uint32 TCPSACKRexmitQueue::checkRexmitQueueForSackedOrRexmittedSegments ( uint32  fromSeq) [virtual]

Checks rexmit queue for sacked of rexmitted segments and returns a certain offset (contiguous sacked or rexmitted region) to forward snd->nxt. It is called before retransmitting data.

Referenced by TCPConnection::sendSegment().

{
    uint32 counter = 0;

    if (fromSeqNum==0 || rexmitQueue.empty() || !(seqLE(begin,fromSeqNum) && seqLE(fromSeqNum,end)))
        return counter;

    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end())
    {
        // search for fromSeqNum (snd_nxt)
        if (i->beginSeqNum == fromSeqNum)
            break;
        else
            i++;
    }

    // search for adjacent sacked/rexmitted regions
    while (i!=rexmitQueue.end())
    {
        if (i->sacked || i->rexmitted)
        {
            counter = counter + (i->endSeqNum - i->beginSeqNum);

            // adjacent regions?
            uint32 tmp = i->endSeqNum;
            i++;
            if (i->beginSeqNum != tmp)
                break;
        }
        else
            break;
    }
    return counter;
}
void TCPSACKRexmitQueue::discardUpTo ( uint32  seqNum) [virtual]

Tells the queue that bytes up to (but NOT including) seqNum have been transmitted and ACKed, so they can be removed from the queue.

Referenced by TCPConnection::processAckInEstabEtc(), TCPConnection::processRstInSynReceived(), and TCPConnection::processSegmentInSynSent().

{
    if (rexmitQueue.empty())
        return;

    ASSERT(seqLE(begin,seqNum) && seqLE(seqNum,end));
    begin = seqNum;

    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end()) // discard/delete regions from rexmit queue, which have been acked
    {
        if (seqLess(i->beginSeqNum,begin))
            i = rexmitQueue.erase(i);
        else
            i++;
    }

    // update begin and end of rexmit queue
    if (rexmitQueue.empty())
        begin = end = 0;
    else
    {
        i = rexmitQueue.begin();
        begin = i->beginSeqNum;
        i = rexmitQueue.end();
        end = i->endSeqNum;
    }
}
void TCPSACKRexmitQueue::enqueueSentData ( uint32  fromSeqNum,
uint32  toSeqNum 
) [virtual]

Inserts sent data to the rexmit queue.

Referenced by TCPConnection::sendSegment().

{
    bool found = false;

    tcpEV << "rexmitQ: " << str() << " enqueueSentData [" << fromSeqNum << ".." << toSeqNum << ")\n";

    Region region;
    region.beginSeqNum = fromSeqNum;
    region.endSeqNum = toSeqNum;
    region.sacked = false;
    region.rexmitted = false;

    if (getQueueLength()==0)
    {
        begin = fromSeqNum;
        end = toSeqNum;
        rexmitQueue.push_back(region);
//        tcpEV << "rexmitQ: rexmitQLength=" << getQueueLength() << "\n";
        return;
    }

    if (seqLE(begin,fromSeqNum) && seqLE(toSeqNum,end))
    {
        // Search for region in queue!
        RexmitQueue::iterator i = rexmitQueue.begin();
        while (i!=rexmitQueue.end())
        {
            if (i->beginSeqNum == fromSeqNum && i->endSeqNum == toSeqNum)
            {
                i->rexmitted = true; // set rexmitted bit
                found = true;
            }
            i++;
        }
    }

    if (!found)
    {
        end = toSeqNum;
        rexmitQueue.push_back(region);
    }
//    tcpEV << "rexmitQ: rexmitQLength=" << getQueueLength() << "\n";
}
uint32 TCPSACKRexmitQueue::getAmountOfSackedBytes ( uint32  seqNum) [virtual]

Returns amount of sacked bytes above seqNum.

Referenced by TCPConnection::isLost().

{
    uint32 bytes = 0;
    uint32 counter = 0;

    if (rexmitQueue.empty() || seqGE(seqNum,end))
        return counter;

    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end() && seqLess(i->beginSeqNum, seqNum)) // search for seqNum
    {
        i++;
        if (i->beginSeqNum == seqNum)
            break;
    }

    ASSERT(seqLE(seqNum,i->beginSeqNum) || seqGE(seqNum,--i->endSeqNum));

    while (i!=rexmitQueue.end())
    {
        if (i->sacked)
        {
            counter++;
            bytes = bytes + (i->endSeqNum - i->beginSeqNum);
        }
        i++;
    }
    return bytes;
}
uint32 TCPSACKRexmitQueue::getBufferEndSeq ( ) [virtual]

Returns the sequence number of the last byte stored in the buffer plus one. (The first byte of the next send operation would get this sequence number.)

Referenced by TCPConnection::processRstInSynReceived().

{
    return end;
}
uint32 TCPSACKRexmitQueue::getBufferStartSeq ( ) [virtual]

Returns the sequence number of the first byte stored in the buffer.

{
    return begin;
}
uint32 TCPSACKRexmitQueue::getHighestRexmittedSeqNum ( ) [virtual]

Returns the highest sequence number rexmitted by data sender.

Referenced by TCPConnection::nextSeg(), TCPConnection::retransmitOneSegment(), TCPConnection::sendData(), TCPConnection::sendSegmentDuringLossRecoveryPhase(), and TCPConnection::setPipe().

{
    uint32 tmp_highest_rexmitted = 0;

    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end())
    {
        if (i->rexmitted)
            tmp_highest_rexmitted = i->endSeqNum;
        i++;
    }
    return tmp_highest_rexmitted;
}
uint32 TCPSACKRexmitQueue::getHighestSackedSeqNum ( ) [virtual]

Returns the highest sequence number sacked by data receiver.

Referenced by TCPConnection::nextSeg().

{
    uint32 tmp_highest_sacked = 0;

    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end())
    {
        if (i->sacked)
            tmp_highest_sacked = i->endSeqNum;
        i++;
    }
    return tmp_highest_sacked;
}
uint32 TCPSACKRexmitQueue::getNumOfDiscontiguousSacks ( uint32  seqNum) [virtual]

Returns the number of discontiguous sacked regions (SACKed sequences) above seqNum.

Referenced by TCPConnection::isLost().

{
    uint32 counter = 0;

    if (rexmitQueue.empty() || seqGE(seqNum,end))
        return counter;

    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end() && seqLess(i->beginSeqNum, seqNum)) // search for seqNum
    {
        i++;
        if (i->beginSeqNum == seqNum)
            break;
    }

    ASSERT(seqLE(seqNum,i->beginSeqNum) || seqGE(seqNum,--i->endSeqNum));

    // search for discontiguous sacked regions
    while (i!=rexmitQueue.end())
    {
        if (i->sacked)
        {
            counter++;
            uint32 tmp = i->endSeqNum;
            i++;
            while (i->sacked && i->beginSeqNum == tmp && i!=rexmitQueue.end()) // adjacent sacked regions?
            {
                tmp = i->endSeqNum;
                i++;
            }
        }
        else
            i++;
    }
    return counter;
}
uint32 TCPSACKRexmitQueue::getQueueLength ( ) [virtual]

Returns the number of blocks currently buffered in queue.

Referenced by enqueueSentData().

{
    return rexmitQueue.size();
}
bool TCPSACKRexmitQueue::getSackedBit ( uint32  seqNum) [virtual]

Returns SackedBit value of seqNum.

Referenced by TCPConnection::nextSeg(), and TCPConnection::setPipe().

{
    bool found = false;

    if (seqLE(begin,seqNum))
    {
        RexmitQueue::iterator i = rexmitQueue.begin();
        while (i!=rexmitQueue.end())
        {
            if (i->beginSeqNum == seqNum) // Search for region in queue!
            {
                found = i->sacked;
                break;
            }
            i++;
        }
    }
    return found;
}
uint32 TCPSACKRexmitQueue::getTotalAmountOfSackedBytes ( ) [virtual]

Returns total amount of sacked bytes. Corresponds to update() function from RFC 3517.

Referenced by TCPConnection::processSACKOption().

{
    uint32 bytes = 0;
    uint32 counter = 0;

    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end())
    {
        if (i->sacked)
        {
            counter++;
            bytes = bytes + (i->endSeqNum - i->beginSeqNum);
        }
        i++;
    }
    return bytes;
}
void TCPSACKRexmitQueue::info ( ) [virtual]

Prints the current rexmitQueue status for debug purposes.

{
    str();
    RexmitQueue::iterator i = rexmitQueue.begin();
    uint j = 1;
    while (i!=rexmitQueue.end())
    {
        tcpEV << j << ". region: [" << i->beginSeqNum << ".." << i->endSeqNum << ") \t sacked=" << i->sacked << "\t rexmitted=" << i->rexmitted << "\n";
        i++;
        j++;
    }
}
void TCPSACKRexmitQueue::init ( uint32  seqNum) [virtual]

Initialize the object. The startSeq parameter tells what sequence number the first byte of app data should get. This is usually ISS+1 because SYN consumes one byte in the sequence number space.

init() may be called more than once; every call flushes the existing contents of the queue.

Referenced by TCPConnection::selectInitialSeqNum().

{
    begin = seqNum;
    end = seqNum;
}
void TCPSACKRexmitQueue::resetRexmittedBit ( ) [virtual]

Called when REXMIT timer expired. Resets rexmitted bit of all segments in rexmit queue.

Referenced by TCPBaseAlg::processRexmitTimer().

{
    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end())
    {
        i->rexmitted = false; // reset rexmitted bit
        i++;
    }
}
void TCPSACKRexmitQueue::resetSackedBit ( ) [virtual]

Called when REXMIT timer expired. Resets sacked bit of all segments in rexmit queue.

Referenced by TCPBaseAlg::processRexmitTimer().

{
    RexmitQueue::iterator i = rexmitQueue.begin();
    while (i!=rexmitQueue.end())
    {
        i->sacked = false; // reset sacked bit
        i++;
    }
}
virtual void TCPSACKRexmitQueue::setConnection ( TCPConnection _conn) [inline, virtual]

Set the connection that owns this queue.

Referenced by TCPConnection::cloneListeningConnection(), and TCPConnection::initConnection().

{conn = _conn;}
void TCPSACKRexmitQueue::setSackedBit ( uint32  fromSeqNum,
uint32  toSeqNum 
) [virtual]

Called when data sender received selective acknowledgments. Tells the queue which bytes have been transmitted and SACKed, so they can be skipped if retransmitting segments as long as REXMIT timer did not expired.

Referenced by TCPConnection::processSACKOption().

{
    bool found = false;

    if (seqLE(toSeqNum,end))
    {
        RexmitQueue::iterator i = rexmitQueue.begin();
        while (i!=rexmitQueue.end())
        {
            if (i->beginSeqNum == fromSeqNum && seqGE(toSeqNum, i->endSeqNum)) // Search for LE of region in queue!
            {
                i->sacked = true; // set sacked bit
                found = true;
                i++;
                while (seqGE(toSeqNum, i->endSeqNum) && i!=rexmitQueue.end()) // Search for RE of region in queue!
                {
                    i->sacked = true; // set sacked bit
                    i++;
                }
            }
            else
                i++;
        }
    }

    if (!found)
        tcpEV << "FAILED to set sacked bit for region: [" << fromSeqNum << ".." << toSeqNum << "). Not found in retransmission queue.\n";
}
std::string TCPSACKRexmitQueue::str ( ) const [virtual]

Returns a string for debug purposes.

Referenced by enqueueSentData(), and info().

{
    std::stringstream out;
    out << "[" << begin << ".." << end << ")";
    return out.str();
}

Member Data Documentation


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