IPFragBuf Class Reference

#include <IPFragBuf.h>

List of all members.


Detailed Description

Reassembly buffer for fragmented IP datagrams.

Public Member Functions

 IPFragBuf ()
 ~IPFragBuf ()
void init (ICMP *icmp)
IPDatagram * addFragment (IPDatagram *datagram, simtime_t now)
void purgeStaleFragments (simtime_t lastupdate)

Protected Types

typedef std::map< Key,
DatagramBuffer
Buffers

Protected Attributes

Buffers bufs
ICMPicmpModule

Classes

struct  DatagramBuffer
struct  Key

Member Typedef Documentation

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


Constructor & Destructor Documentation

IPFragBuf::IPFragBuf (  ) 

Ctor.

00028 {
00029     icmpModule = NULL;
00030 }

IPFragBuf::~IPFragBuf (  ) 

Dtor.

00033 {
00034 }


Member Function Documentation

void IPFragBuf::init ( ICMP icmp  ) 

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

Referenced by IP::initialize().

00037 {
00038     icmpModule = icmp;
00039 }

IPDatagram * IPFragBuf::addFragment ( IPDatagram *  datagram,
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.

Referenced by IP::reassembleAndDeliver().

00042 {
00043     // find datagram buffer
00044     Key key;
00045     key.id = datagram->getIdentification();
00046     key.src = datagram->getSrcAddress();
00047     key.dest = datagram->getDestAddress();
00048 
00049     Buffers::iterator i = bufs.find(key);
00050 
00051     DatagramBuffer *buf = NULL;
00052     if (i==bufs.end())
00053     {
00054         // this is the first fragment of that datagram, create reassembly buffer for it
00055         buf = &bufs[key];
00056         buf->datagram = NULL;
00057     }
00058     else
00059     {
00060         // use existing buffer
00061         buf = &(i->second);
00062     }
00063 
00064     // add fragment into reassembly buffer
00065     int bytes = datagram->getByteLength() - datagram->getHeaderLength();
00066     bool isComplete = buf->buf.addFragment(datagram->getFragmentOffset(),
00067                                            datagram->getFragmentOffset() + bytes,
00068                                            !datagram->getMoreFragments());
00069 
00070     // store datagram. Only one fragment carries the actual modelled
00071     // content (getEncapsulatedMsg()), other (empty) ones are only
00072     // preserved so that we can send them in ICMP if reassembly times out.
00073     if (datagram->getEncapsulatedMsg())
00074     {
00075         delete buf->datagram;
00076         buf->datagram = datagram;
00077     }
00078     else
00079     {
00080         delete datagram;
00081     }
00082 
00083     // do we have the complete datagram?
00084     if (isComplete)
00085     {
00086         // datagram complete: deallocate buffer and return complete datagram
00087         IPDatagram *ret = buf->datagram;
00088         ret->setByteLength(ret->getHeaderLength()+buf->buf.getTotalLength());
00089         bufs.erase(i);
00090         return ret;
00091     }
00092     else
00093     {
00094         // there are still missing fragments
00095         buf->lastupdate = now;
00096         return NULL;
00097     }
00098 }

void IPFragBuf::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.

Referenced by IP::reassembleAndDeliver().

00101 {
00102     // this method shouldn't be called too often because iteration on
00103     // an std::map is *very* slow...
00104 
00105     ASSERT(icmpModule);
00106 
00107     for (Buffers::iterator i=bufs.begin(); i!=bufs.end(); )
00108     {
00109         // if too old, remove it
00110         DatagramBuffer& buf = i->second;
00111         if (buf.lastupdate < lastupdate)
00112         {
00113             // send ICMP error
00114             EV << "datagram fragment timed out in reassembly buffer, sending ICMP_TIME_EXCEEDED\n";
00115             icmpModule->sendErrorMessage(buf.datagram, ICMP_TIME_EXCEEDED, 0);
00116 
00117             // delete
00118             Buffers::iterator oldi = i++;
00119             bufs.erase(oldi);
00120         }
00121         else
00122         {
00123             ++i;
00124         }
00125     }
00126 }


Member Data Documentation

Buffers IPFragBuf::bufs [protected]

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