00001 // 00002 // Copyright (C) 2004-2005 Andras Varga 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public License 00015 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 #ifndef __INET_REASSEMBLYBUFFER_H 00019 #define __INET_REASSEMBLYBUFFER_H 00020 00021 #include <map> 00022 #include <vector> 00023 #include "INETDefs.h" 00024 00025 00031 class INET_API ReassemblyBuffer 00032 { 00033 protected: 00034 // stores an offset range 00035 struct Region 00036 { 00037 ushort beg; // first offset stored 00038 ushort end; // last+1 offset stored 00039 bool islast; // if this region represents the last bytes of the datagram 00040 }; 00041 00042 typedef std::vector<Region> RegionVector; 00043 00044 // 00045 // Thinking of IP/IPv6 fragmentation, 99% of the time fragments 00046 // will arrive in order and none gets lost, so we have to 00047 // handle this case very efficiently. For this purpose 00048 // we'll store the offset of the first and last+1 byte we have 00049 // (main.beg, main.end variables), and keep extending this range 00050 // as new fragments arrive. If we receive non-connecting fragments, 00051 // put them aside into buf until new fragments come and fill the gap. 00052 // 00053 Region main; // offset range we already have 00054 RegionVector *fragments; // only used if we receive disjoint fragments 00055 00056 protected: 00057 void merge(ushort beg, ushort end, bool islast); 00058 void mergeFragments(); 00059 00060 public: 00064 ReassemblyBuffer(); 00065 00069 ~ReassemblyBuffer(); 00070 00075 bool addFragment(ushort beg, ushort end, bool islast); 00076 00081 ushort getTotalLength() const {return main.end;} 00082 }; 00083 00084 #endif 00085