ReassemblyBuffer Class Reference

#include <ReassemblyBuffer.h>

List of all members.


Detailed Description

Generic reassembly buffer for a fragmented datagram (or a fragmented anything).

Currently used in IPFragBuf and IPv6FragBuf.

Public Member Functions

 ReassemblyBuffer ()
 ~ReassemblyBuffer ()
bool addFragment (ushort beg, ushort end, bool islast)
ushort getTotalLength () const

Protected Types

typedef std::vector< RegionRegionVector

Protected Member Functions

void merge (ushort beg, ushort end, bool islast)
void mergeFragments ()

Protected Attributes

Region main
RegionVectorfragments

Classes

struct  Region


Member Typedef Documentation

typedef std::vector<Region> ReassemblyBuffer::RegionVector [protected]


Constructor & Destructor Documentation

ReassemblyBuffer::ReassemblyBuffer (  ) 

Ctor.

00026 {
00027     main.beg = main.end = 0;
00028     main.islast = false;
00029     fragments = NULL;
00030 }

ReassemblyBuffer::~ReassemblyBuffer (  ) 

Dtor.

00033 {
00034     delete fragments;
00035 }


Member Function Documentation

void ReassemblyBuffer::merge ( ushort  beg,
ushort  end,
bool  islast 
) [protected]

Referenced by addFragment().

00046 {
00047     if (main.end==beg)
00048     {
00049         // most typical case (<95%): new fragment follows last one
00050         main.end = end;
00051         if (islast)
00052             main.islast = true;
00053         if (fragments)
00054             mergeFragments();
00055     }
00056     else if (main.beg==end)
00057     {
00058         // new fragment precedes what we already have
00059         main.beg = beg;
00060         if (fragments)
00061             mergeFragments();
00062     }
00063     else if (main.end<beg || main.beg>end)
00064     {
00065         // disjoint fragment, store it until another fragment fills in the gap
00066         if (!fragments)
00067             fragments = new RegionVector();
00068         Region r;
00069         r.beg = beg;
00070         r.end = end;
00071         r.islast = islast;
00072         fragments->push_back(r);
00073     }
00074     else
00075     {
00076         // overlapping is not possible;
00077         // fragment's range already contained in buffer (probably duplicate fragment)
00078     }
00079 }

void ReassemblyBuffer::mergeFragments (  )  [protected]

Referenced by merge().

00082 {
00083     RegionVector& frags = *fragments;
00084 
00085     bool oncemore;
00086     do
00087     {
00088         oncemore = false;
00089         for (RegionVector::iterator i=frags.begin(); i!=frags.end(); )
00090         {
00091             bool deleteit = false;
00092             Region& frag = *i;
00093             if (main.end==frag.beg)
00094             {
00095                 main.end = frag.end;
00096                 if (frag.islast)
00097                     main.islast = true;
00098                 deleteit = true;
00099             }
00100             else if (main.beg==frag.end)
00101             {
00102                 main.beg = frag.beg;
00103                 deleteit = true;
00104             }
00105             else if (main.beg<=frag.beg && main.end>=frag.end)
00106             {
00107                 // we already have this region (duplicate fragment), delete it
00108                 deleteit = true;
00109             }
00110 
00111             if (deleteit)
00112             {
00113                 // deletion is tricky because erase() invalidates iterator
00114                 int pos = i - frags.begin();
00115                 frags.erase(i);
00116                 i = frags.begin() + pos;
00117                 oncemore = true;
00118             }
00119             else
00120             {
00121                 ++i;
00122             }
00123         }
00124     }
00125     while (oncemore);
00126 }

bool ReassemblyBuffer::addFragment ( ushort  beg,
ushort  end,
bool  islast 
)

Add a fragment, and returns true if reassembly has completed (i.e. we have everything from offset 0 to the last fragment).

Referenced by IPv6FragBuf::addFragment(), and IPFragBuf::addFragment().

00038 {
00039     merge(beg, end, islast);
00040 
00041     // do we have the complete datagram?
00042     return main.beg==0 && main.islast;
00043 }

ushort ReassemblyBuffer::getTotalLength (  )  const [inline]

Returns the total (assembled) length of the datagram. Can only be called after addFragment() returned true.

Referenced by IPv6FragBuf::addFragment(), and IPFragBuf::addFragment().

00081 {return main.end;}


Member Data Documentation


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

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