#include <IPv6FragBuf.h>
Classes | |
struct | DatagramBuffer |
struct | Key |
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 |
Reassembly buffer for fragmented IPv6 datagrams.
Definition at line 34 of file IPv6FragBuf.h.
typedef std::map<Key,DatagramBuffer> IPv6FragBuf::Buffers [protected] |
Definition at line 62 of file IPv6FragBuf.h.
IPv6FragBuf::IPv6FragBuf | ( | ) |
IPv6FragBuf::~IPv6FragBuf | ( | ) |
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.
Definition at line 43 of file IPv6FragBuf.cc.
{ // find datagram buffer Key key; key.id = fh->getIdentification(); key.src = datagram->getSrcAddress(); key.dest = datagram->getDestAddress(); Buffers::iterator i = bufs.find(key); DatagramBuffer *buf = NULL; if (i==bufs.end()) { // this is the first fragment of that datagram, create reassembly buffer for it buf = &bufs[key]; buf->datagram = NULL; } else { // use existing buffer buf = &(i->second); } // add fragment into reassembly buffer // FIXME next lines aren't correct: check 4.5 of RFC 2460 regarding Unfragmentable part, Fragmentable part, etc int bytes = datagram->getByteLength() - datagram->calculateHeaderByteLength(); bool isComplete = buf->buf.addFragment(fh->getFragmentOffset(), fh->getFragmentOffset() + bytes, !fh->getMoreFragments()); // store datagram. Only one fragment carries the actual modelled // content (getEncapsulatedMsg()), other (empty) ones are only // preserved so that we can send them in ICMP if reassembly times out. if (datagram->getEncapsulatedMsg()) { delete buf->datagram; buf->datagram = datagram; } else { delete datagram; } // do we have the complete datagram? if (isComplete) { // datagram complete: deallocate buffer and return complete datagram IPv6Datagram *ret = buf->datagram; ret->setByteLength(ret->calculateHeaderByteLength()+buf->buf.getTotalLength()); // FIXME cf with 4.5 of RFC 2460 //TODO: remove extension header IPv6FragmentHeader; maybe not here but when datagram gets inserted into the reassembly buffer --Andras bufs.erase(i); return ret; } else { // there are still missing fragments buf->lastupdate = now; return NULL; } }
void IPv6FragBuf::init | ( | ICMPv6 * | icmp | ) |
Initialize fragmentation buffer. ICMP module is needed for sending TIME_EXCEEDED ICMP message in purgeStaleFragments().
Definition at line 38 of file IPv6FragBuf.cc.
Referenced by IPv6::initialize().
{ icmpModule = icmp; }
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.
Definition at line 104 of file IPv6FragBuf.cc.
{ // this method shouldn't be called too often because iteration on // an std::map is *very* slow... ASSERT(icmpModule); for (Buffers::iterator i=bufs.begin(); i!=bufs.end(); ) { // if too old, remove it DatagramBuffer& buf = i->second; if (buf.lastupdate < lastupdate) { // send ICMP error EV << "datagram fragment timed out in reassembly buffer, sending ICMP_TIME_EXCEEDED\n"; icmpModule->sendErrorMessage(buf.datagram, ICMPv6_TIME_EXCEEDED, 0); // delete Buffers::iterator oldi = i++; bufs.erase(oldi); } else { ++i; } } }
Buffers IPv6FragBuf::bufs [protected] |
Definition at line 65 of file IPv6FragBuf.h.
Referenced by addFragment(), and purgeStaleFragments().
ICMPv6* IPv6FragBuf::icmpModule [protected] |
Definition at line 68 of file IPv6FragBuf.h.
Referenced by init(), IPv6FragBuf(), and purgeStaleFragments().