#include <IPv6FragBuf.h>
Public Member Functions | |
IPv6FragBuf () | |
~IPv6FragBuf () | |
void | init (ICMPv6 *icmp) |
IPv6Datagram * | addFragment (IPv6Datagram *datagram, IPv6FragmentHeader *fh, simtime_t now) |
void | purgeStaleFragments (simtime_t lastupdate) |
Protected Types | |
typedef std::map< Key, DatagramBuffer > | Buffers |
Protected Attributes | |
Buffers | bufs |
ICMPv6 * | icmpModule |
Classes | |
struct | DatagramBuffer |
struct | Key |
typedef std::map<Key,DatagramBuffer> IPv6FragBuf::Buffers [protected] |
IPv6FragBuf::IPv6FragBuf | ( | ) |
void IPv6FragBuf::init | ( | ICMPv6 * | icmp | ) |
Initialize fragmentation buffer. ICMP module is needed for sending TIME_EXCEEDED ICMP message in purgeStaleFragments().
Referenced by IPv6::initialize().
00039 { 00040 icmpModule = icmp; 00041 }
IPv6Datagram * IPv6FragBuf::addFragment | ( | IPv6Datagram * | datagram, | |
IPv6FragmentHeader * | fh, | |||
simtime_t | now | |||
) |
Takes a fragment and inserts it into the reassembly buffer. If this fragment completes a datagram, the full reassembled datagram is returned, otherwise NULL.
00044 { 00045 // find datagram buffer 00046 Key key; 00047 key.id = fh->getIdentification(); 00048 key.src = datagram->getSrcAddress(); 00049 key.dest = datagram->getDestAddress(); 00050 00051 Buffers::iterator i = bufs.find(key); 00052 00053 DatagramBuffer *buf = NULL; 00054 if (i==bufs.end()) 00055 { 00056 // this is the first fragment of that datagram, create reassembly buffer for it 00057 buf = &bufs[key]; 00058 buf->datagram = NULL; 00059 } 00060 else 00061 { 00062 // use existing buffer 00063 buf = &(i->second); 00064 } 00065 00066 // add fragment into reassembly buffer 00067 // FIXME next lines aren't correct: check 4.5 of RFC 2460 regarding Unfragmentable part, Fragmentable part, etc 00068 int bytes = datagram->getByteLength() - datagram->calculateHeaderByteLength(); 00069 bool isComplete = buf->buf.addFragment(fh->getFragmentOffset(), 00070 fh->getFragmentOffset() + bytes, 00071 !fh->getMoreFragments()); 00072 00073 // store datagram. Only one fragment carries the actual modelled 00074 // content (getEncapsulatedMsg()), other (empty) ones are only 00075 // preserved so that we can send them in ICMP if reassembly times out. 00076 if (datagram->getEncapsulatedMsg()) 00077 { 00078 delete buf->datagram; 00079 buf->datagram = datagram; 00080 } 00081 else 00082 { 00083 delete datagram; 00084 } 00085 00086 // do we have the complete datagram? 00087 if (isComplete) 00088 { 00089 // datagram complete: deallocate buffer and return complete datagram 00090 IPv6Datagram *ret = buf->datagram; 00091 ret->setByteLength(ret->calculateHeaderByteLength()+buf->buf.getTotalLength()); // FIXME cf with 4.5 of RFC 2460 00092 bufs.erase(i); 00093 return ret; 00094 } 00095 else 00096 { 00097 // there are still missing fragments 00098 buf->lastupdate = now; 00099 return NULL; 00100 } 00101 }
void IPv6FragBuf::purgeStaleFragments | ( | simtime_t | lastupdate | ) |
Throws out all fragments which are incomplete and their last update (last fragment arrival) was before "lastupdate", and sends ICMP TIME EXCEEDED message about them.
Timeout should be between 60 seconds and 120 seconds (RFC1122). This method should be called more frequently, maybe every 10..30 seconds or so.
00104 { 00105 // this method shouldn't be called too often because iteration on 00106 // an std::map is *very* slow... 00107 00108 ASSERT(icmpModule); 00109 00110 for (Buffers::iterator i=bufs.begin(); i!=bufs.end(); ) 00111 { 00112 // if too old, remove it 00113 DatagramBuffer& buf = i->second; 00114 if (buf.lastupdate < lastupdate) 00115 { 00116 // send ICMP error 00117 EV << "datagram fragment timed out in reassembly buffer, sending ICMP_TIME_EXCEEDED\n"; 00118 icmpModule->sendErrorMessage(buf.datagram, ICMPv6_TIME_EXCEEDED, 0); 00119 00120 // delete 00121 Buffers::iterator oldi = i++; 00122 bufs.erase(oldi); 00123 } 00124 else 00125 { 00126 ++i; 00127 } 00128 } 00129 }
Buffers IPv6FragBuf::bufs [protected] |
Referenced by addFragment(), and purgeStaleFragments().
ICMPv6* IPv6FragBuf::icmpModule [protected] |
Referenced by init(), IPv6FragBuf(), and purgeStaleFragments().