#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 |
|
|
|
Ctor. 00031 { 00032 icmpModule = NULL; 00033 }
|
|
Dtor. 00036 { 00037 }
|
|
Takes a fragment and inserts it into the reassembly buffer. If this fragment completes a datagram, the full reassembled datagram is returned, otherwise NULL. 00045 { 00046 // find datagram buffer 00047 Key key; 00048 key.id = fh->identification(); 00049 key.src = datagram->srcAddress(); 00050 key.dest = datagram->destAddress(); 00051 00052 Buffers::iterator i = bufs.find(key); 00053 00054 DatagramBuffer *buf = NULL; 00055 if (i==bufs.end()) 00056 { 00057 // this is the first fragment of that datagram, create reassembly buffer for it 00058 buf = &bufs[key]; 00059 buf->datagram = NULL; 00060 } 00061 else 00062 { 00063 // use existing buffer 00064 buf = &(i->second); 00065 } 00066 00067 // add fragment into reassembly buffer 00068 // FIXME next lines aren't correct: check 4.5 of RFC 2460 regarding Unfragmentable part, Fragmentable part, etc 00069 int bytes = datagram->byteLength() - datagram->calculateHeaderByteLength(); 00070 bool isComplete = buf->buf.addFragment(fh->fragmentOffset(), 00071 fh->fragmentOffset() + bytes, 00072 !fh->moreFragments()); 00073 00074 // store datagram. Only one fragment carries the actual modelled 00075 // content (encapsulatedMsg()), other (empty) ones are only 00076 // preserved so that we can send them in ICMP if reassembly times out. 00077 if (datagram->encapsulatedMsg()) 00078 { 00079 delete buf->datagram; 00080 buf->datagram = datagram; 00081 } 00082 else 00083 { 00084 delete datagram; 00085 } 00086 00087 // do we have the complete datagram? 00088 if (isComplete) 00089 { 00090 // datagram complete: deallocate buffer and return complete datagram 00091 IPv6Datagram *ret = buf->datagram; 00092 ret->setByteLength(ret->calculateHeaderByteLength()+buf->buf.totalLength()); // FIXME cf with 4.5 of RFC 2460 00093 bufs.erase(i); 00094 return ret; 00095 } 00096 else 00097 { 00098 // there are still missing fragments 00099 buf->lastupdate = now; 00100 return NULL; 00101 } 00102 }
|
|
Initialize fragmentation buffer. ICMP module is needed for sending TIME_EXCEEDED ICMP message in purgeStaleFragments(). 00040 { 00041 icmpModule = icmp; 00042 }
|
|
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. 00105 { 00106 // this method shouldn't be called too often because iteration on 00107 // an std::map is *very* slow... 00108 00109 ASSERT(icmpModule); 00110 00111 for (Buffers::iterator i=bufs.begin(); i!=bufs.end(); ) 00112 { 00113 // if too old, remove it 00114 DatagramBuffer& buf = i->second; 00115 if (buf.lastupdate < lastupdate) 00116 { 00117 // send ICMP error 00118 EV << "datagram fragment timed out in reassembly buffer, sending ICMP_TIME_EXCEEDED\n"; 00119 icmpModule->sendErrorMessage(buf.datagram, ICMPv6_TIME_EXCEEDED, 0); 00120 00121 // delete 00122 Buffers::iterator oldi = i++; 00123 bufs.erase(oldi); 00124 } 00125 else 00126 { 00127 ++i; 00128 } 00129 } 00130 }
|
|
|
|
|