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, DatagramBufferBuffers

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.

00031 {
00032     icmpModule = NULL;
00033 }

IPv6FragBuf::~IPv6FragBuf (  ) 

Dtor.

00036 {
00037 }


Member Function Documentation

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.

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 }

void IPv6FragBuf::init ( ICMPv6 icmp  ) 

Initialize fragmentation buffer. ICMP module is needed for sending TIME_EXCEEDED ICMP message in purgeStaleFragments().

00040 {
00041     icmpModule = icmp;
00042 }

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.

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 }


Member Data Documentation

Buffers IPv6FragBuf::bufs [protected]

ICMPv6* IPv6FragBuf::icmpModule [protected]


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:20:21 2007 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.7