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

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 totalLength () 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.

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

ReassemblyBuffer::~ReassemblyBuffer  ) 
 

Dtor.

00034 {
00035     delete fragments;
00036 }


Member Function Documentation

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).

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

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

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

void ReassemblyBuffer::mergeFragments  )  [protected]
 

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

ushort ReassemblyBuffer::totalLength  )  const [inline]
 

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

00082 {return main.end;}


Member Data Documentation

RegionVector* ReassemblyBuffer::fragments [protected]
 

Region ReassemblyBuffer::main [protected]
 


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