Bug 1422 - Fix memory leak in IPv6 fragmentation
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Tue, 22 May 2012 21:44:19 +0200
changeset 8793 9c59d55abcce
parent 8792 8f15de62d18e
child 8797 cf6b2a864fb6
Bug 1422 - Fix memory leak in IPv6 fragmentation
src/internet/model/ipv4-l3-protocol.h
src/internet/model/ipv6-extension.cc
src/internet/model/ipv6-extension.h
--- a/src/internet/model/ipv4-l3-protocol.h	Tue May 22 21:41:55 2012 -0700
+++ b/src/internet/model/ipv4-l3-protocol.h	Tue May 22 21:44:19 2012 +0200
@@ -370,10 +370,6 @@
      */
     std::list<std::pair<Ptr<Packet>, uint16_t> > m_fragments;
 
-    /**
-     * \brief Number of references.
-     */
-    mutable uint32_t m_refCount;
   };
 
   typedef std::map< std::pair<uint64_t, uint32_t>, Ptr<Fragments> > MapFragments_t;
--- a/src/internet/model/ipv6-extension.cc	Tue May 22 21:41:55 2012 -0700
+++ b/src/internet/model/ipv6-extension.cc	Tue May 22 21:44:19 2012 +0200
@@ -347,7 +347,7 @@
       m_fragments.insert (std::make_pair (fragmentsId, fragments));
       EventId timeout = Simulator::Schedule (Seconds (60),
                                              &Ipv6ExtensionFragment::HandleFragmentsTimeout, this,
-                                             fragmentsId, fragments, ipHeader);
+                                             fragmentsId, ipHeader);
       fragments->SetTimeoutEventId (timeout);
     }
   else
@@ -548,8 +548,15 @@
 }
 
 
-void Ipv6ExtensionFragment::HandleFragmentsTimeout (std::pair<Ipv6Address, uint32_t> fragmentsId, Ptr<Fragments> fragments, Ipv6Header & ipHeader)
+void Ipv6ExtensionFragment::HandleFragmentsTimeout (std::pair<Ipv6Address, uint32_t> fragmentsId,
+                                                    Ipv6Header & ipHeader)
 {
+  Ptr<Fragments> fragments;
+
+  MapFragments_t::iterator it = m_fragments.find (fragmentsId);
+  NS_ASSERT_MSG(it != m_fragments.end (), "IPv6 Fragment timeout reached for non-existent fragment");
+  fragments = it->second;
+
   Ptr<Packet> packet = fragments->GetPartialPacket ();
 
   packet->AddHeader (ipHeader);
@@ -557,7 +564,6 @@
   // if we have at least 8 bytes, we can send an ICMP.
   if ( packet->GetSize () > 8 )
     {
-
       Ptr<Icmpv6L4Protocol> icmp = GetNode ()->GetObject<Icmpv6L4Protocol> ();
       icmp->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_FRAGTIME);
     }
@@ -580,7 +586,7 @@
 {
   std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
 
-  for (it = m_fragments.begin (); it != m_fragments.end (); it++)
+  for (it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
     {
       if (it->second > fragmentOffset)
         {
@@ -588,12 +594,12 @@
         }
     }
 
-  if (it == m_fragments.end ())
+  if (it == m_packetFragments.end ())
     {
       m_moreFragment = moreFragment;
     }
 
-  m_fragments.insert (it, std::make_pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
+  m_packetFragments.insert (it, std::make_pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
 }
 
 void Ipv6ExtensionFragment::Fragments::SetUnfragmentablePart (Ptr<Packet> unfragmentablePart)
@@ -603,13 +609,13 @@
 
 bool Ipv6ExtensionFragment::Fragments::IsEntire () const
 {
-  bool ret = !m_moreFragment && m_fragments.size () > 0;
+  bool ret = !m_moreFragment && m_packetFragments.size () > 0;
 
   if (ret)
     {
       uint16_t lastEndOffset = 0;
 
-      for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
+      for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
         {
           if (lastEndOffset != it->second)
             {
@@ -628,7 +634,7 @@
 {
   Ptr<Packet> p =  m_unfragmentable->Copy ();
 
-  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
+  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
     {
       p->AddAtEnd (it->first);
     }
@@ -651,7 +657,7 @@
 
   uint16_t lastEndOffset = 0;
 
-  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
+  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_packetFragments.begin (); it != m_packetFragments.end (); it++)
     {
       if (lastEndOffset != it->second)
         {
--- a/src/internet/model/ipv6-extension.h	Tue May 22 21:41:55 2012 -0700
+++ b/src/internet/model/ipv6-extension.h	Tue May 22 21:44:19 2012 +0200
@@ -343,7 +343,7 @@
     /**
      * \brief The current fragments.
      */
-    std::list<std::pair<Ptr<Packet>, uint16_t> > m_fragments;
+    std::list<std::pair<Ptr<Packet>, uint16_t> > m_packetFragments;
 
     /**
      * \brief The unfragmentable part.
@@ -351,11 +351,6 @@
     Ptr<Packet> m_unfragmentable;
 
     /**
-     * \brief Number of references.
-     */
-    mutable uint32_t m_refCount;
-
-    /**
      * \brief Timeout handler event
      */
     EventId m_timeoutEventId;
@@ -367,7 +362,7 @@
    * \param ipHeader the IP header of the original packet
    * \param iif Input Interface
    */
-  void HandleFragmentsTimeout (std::pair<Ipv6Address, uint32_t> key, Ptr<Fragments> fragments, Ipv6Header & ipHeader);
+  void HandleFragmentsTimeout (std::pair<Ipv6Address, uint32_t> key, Ipv6Header & ipHeader);
 
   /**
    * \brief Get the packet parts so far received.