TCPVirtualDataRcvQueue Class Reference

#include <TCPVirtualDataRcvQueue.h>

Inheritance diagram for TCPVirtualDataRcvQueue:

TCPReceiveQueue TCPMsgBasedRcvQueue

List of all members.


Detailed Description

Receive queue that manages "virtual bytes", that is, byte counts only.

See also:
TCPVirtualDataSendQueue

Public Member Functions

 TCPVirtualDataRcvQueue ()
virtual ~TCPVirtualDataRcvQueue ()
virtual void init (uint32 startSeq)
virtual std::string info () const
virtual uint32 insertBytesFromSegment (TCPSegment *tcpseg)
virtual cPacket * extractBytesUpTo (uint32 seq)

Protected Types

typedef std::list< RegionRegionList

Protected Member Functions

void merge (uint32 segmentBegin, uint32 segmentEnd)
ulong extractTo (uint32 toSeq)

Protected Attributes

uint32 rcv_nxt
RegionList regionList

Classes

struct  Region

Member Typedef Documentation

typedef std::list<Region> TCPVirtualDataRcvQueue::RegionList [protected]


Constructor & Destructor Documentation

TCPVirtualDataRcvQueue::TCPVirtualDataRcvQueue (  ) 

Ctor.

00025                                                : TCPReceiveQueue()
00026 {
00027 }

TCPVirtualDataRcvQueue::~TCPVirtualDataRcvQueue (  )  [virtual]

Virtual dtor.

00030 {
00031 }


Member Function Documentation

void TCPVirtualDataRcvQueue::merge ( uint32  segmentBegin,
uint32  segmentEnd 
) [protected]

Referenced by insertBytesFromSegment().

00062 {
00063     // Here we have to update our existing regions with the octet range
00064     // tcpseg represents. We either have to insert tcpseg as a separate region
00065     // somewhere, or (if it overlaps with an existing region) extend
00066     // existing regions; we also may have to merge existing regions if
00067     // they become overlapping (or touching) after adding tcpseg.
00068 
00069     Region seg;
00070     seg.begin = segmentBegin;
00071     seg.end = segmentEnd;
00072 
00073     RegionList::iterator i = regionList.begin();
00074     if (i==regionList.end())
00075     {
00076         // insert as first and only region
00077         regionList.insert(regionList.begin(), seg);
00078         return;
00079     }
00080 
00081     // skip regions which fall entirely before seg (no overlap or touching)
00082     while (i!=regionList.end() && seqLess(i->end,seg.begin))
00083     {
00084         ++i;
00085     }
00086 
00087     if (i==regionList.end())
00088     {
00089         // seg is entirely past last region: insert as separate region at end
00090         regionList.insert(regionList.end(), seg);
00091         return;
00092     }
00093 
00094     if (seqLess(seg.end,i->begin))
00095     {
00096         // segment entirely before region "i": insert as separate region before "i"
00097         regionList.insert(i, seg);
00098         return;
00099     }
00100 
00101     if (seqLess(seg.begin,i->begin))
00102     {
00103         // segment starts before region "i": extend region
00104         i->begin = seg.begin;
00105     }
00106 
00107     if (seqLess(i->end,seg.end))
00108     {
00109         // segment ends past end of region "i": extend region
00110         i->end = seg.end;
00111 
00112         // maybe we have to merge region "i" with next one(s)
00113         RegionList::iterator j = i;
00114         ++j;
00115         while (j!=regionList.end() && seqGE(i->end,j->begin)) // while there's overlap
00116         {
00117             // if "j" is longer: extend "i"
00118             if (seqLess(i->end,j->end))
00119                 i->end = j->end;
00120 
00121             // erase "j" (it was merged into "i")
00122             RegionList::iterator oldj = j++;
00123             regionList.erase(oldj);
00124         }
00125     }
00126 }

ulong TCPVirtualDataRcvQueue::extractTo ( uint32  toSeq  )  [protected]

Referenced by extractBytesUpTo(), and TCPMsgBasedRcvQueue::extractBytesUpTo().

00140 {
00141     ASSERT(seqLE(seq,rcv_nxt));
00142 
00143     RegionList::iterator i = regionList.begin();
00144     if (i==regionList.end())
00145         return 0;
00146 
00147     ASSERT(i->begin<i->end); // empty regions cannot exist
00148 
00149     // seq below 1st region
00150     if (seqLE(seq,i->begin))
00151         return 0;
00152 
00153     if (seqLess(seq,i->end))
00154     {
00155         // part of 1st region
00156         ulong octets = seq - i->begin;
00157         i->begin = seq;
00158         return octets;
00159     }
00160     else
00161     {
00162         // full 1st region
00163         ulong octets = i->end - i->begin;
00164         regionList.erase(i);
00165         return octets;
00166     }
00167 }

void TCPVirtualDataRcvQueue::init ( uint32  startSeq  )  [virtual]

Set initial receive sequence number.

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

Referenced by TCPMsgBasedRcvQueue::init().

00034 {
00035     rcv_nxt = startSeq;
00036 }

std::string TCPVirtualDataRcvQueue::info (  )  const [virtual]

Returns a string with region stored.

Reimplemented in TCPMsgBasedRcvQueue.

00039 {
00040     std::string res;
00041     char buf[32];
00042     sprintf(buf, "rcv_nxt=%u ", rcv_nxt);
00043     res = buf;
00044 
00045     for (RegionList::const_iterator i=regionList.begin(); i!=regionList.end(); ++i)
00046     {
00047         sprintf(buf, "[%u..%u) ", i->begin, i->end);
00048         res+=buf;
00049     }
00050     return res;
00051 }

uint32 TCPVirtualDataRcvQueue::insertBytesFromSegment ( TCPSegment tcpseg  )  [virtual]

Called when a TCP segment arrives. Returns sequence number for ACK.

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

Referenced by TCPMsgBasedRcvQueue::insertBytesFromSegment().

00054 {
00055     merge(tcpseg->getSequenceNo(), tcpseg->getSequenceNo()+tcpseg->getPayloadLength());
00056     if (seqGE(rcv_nxt, regionList.begin()->begin))
00057         rcv_nxt = regionList.begin()->end;
00058     return rcv_nxt;
00059 }

cPacket * TCPVirtualDataRcvQueue::extractBytesUpTo ( uint32  seq  )  [virtual]

Should create a packet to be passed up to the app, up to (but NOT including) the given sequence no (usually rcv_nxt). It should return NULL if there's no more data to be passed up -- this method is called several times until it returns NULL.

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

00129 {
00130     ulong numBytes = extractTo(seq);
00131     if (numBytes==0)
00132         return NULL;
00133 
00134     cPacket *msg = new cPacket("data");
00135     msg->setByteLength(numBytes);
00136     return msg;
00137 }


Member Data Documentation

uint32 TCPVirtualDataRcvQueue::rcv_nxt [protected]


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

Generated on Fri Mar 20 18:51:22 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5