Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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 cMessage * 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.

00026                                                : TCPReceiveQueue()
00027 {
00028 }

TCPVirtualDataRcvQueue::~TCPVirtualDataRcvQueue  )  [virtual]
 

Virtual dtor.

00031 {
00032 }


Member Function Documentation

cMessage * 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.

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

ulong TCPVirtualDataRcvQueue::extractTo uint32  toSeq  )  [protected]
 

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

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

Returns a string with region stored.

Reimplemented in TCPMsgBasedRcvQueue.

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

void TCPVirtualDataRcvQueue::init uint32  startSeq  )  [virtual]
 

Set initial receive sequence number.

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

00035 {
00036     rcv_nxt = startSeq;
00037 }

uint32 TCPVirtualDataRcvQueue::insertBytesFromSegment TCPSegment tcpseg  )  [virtual]
 

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

Implements TCPReceiveQueue.

Reimplemented in TCPMsgBasedRcvQueue.

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

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

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


Member Data Documentation

uint32 TCPVirtualDataRcvQueue::rcv_nxt [protected]
 

RegionList TCPVirtualDataRcvQueue::regionList [protected]
 


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:25 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1