#include <ReassemblyBuffer.h>
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< Region > | RegionVector |
Protected Member Functions | |
void | merge (ushort beg, ushort end, bool islast) |
void | mergeFragments () |
Protected Attributes | |
Region | main |
RegionVector * | fragments |
Classes | |
struct | Region |
typedef std::vector<Region> ReassemblyBuffer::RegionVector [protected] |
ReassemblyBuffer::ReassemblyBuffer | ( | ) |
ReassemblyBuffer::~ReassemblyBuffer | ( | ) |
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 }
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().
Region ReassemblyBuffer::main [protected] |
Referenced by addFragment(), merge(), mergeFragments(), and ReassemblyBuffer().
RegionVector* ReassemblyBuffer::fragments [protected] |
Referenced by merge(), mergeFragments(), ReassemblyBuffer(), and ~ReassemblyBuffer().