IPv6FragBuf Class Reference

#include <IPv6FragBuf.h>

List of all members.


Detailed Description

Reassembly buffer for fragmented IPv6 datagrams.

Public Member Functions

 IPv6FragBuf ()
 ~IPv6FragBuf ()
void init (ICMPv6 *icmp)
IPv6DatagramaddFragment (IPv6Datagram *datagram, IPv6FragmentHeader *fh, simtime_t now)
void purgeStaleFragments (simtime_t lastupdate)

Protected Types

typedef std::map< Key,
DatagramBuffer
Buffers

Protected Attributes

Buffers bufs
ICMPv6icmpModule

Classes

struct  DatagramBuffer
struct  Key

Member Typedef Documentation

typedef std::map<Key,DatagramBuffer> IPv6FragBuf::Buffers [protected]


Constructor & Destructor Documentation

IPv6FragBuf::IPv6FragBuf (  ) 

Ctor.

00030 {
00031     icmpModule = NULL;
00032 }

IPv6FragBuf::~IPv6FragBuf (  ) 

Dtor.

00035 {
00036 }


Member Function Documentation

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 }


Member Data Documentation

Referenced by addFragment(), and purgeStaleFragments().


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5