#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 }
|
|
|
|
|
|
|
1.4.1