Implementing notion of default routes (useful for Flooding scenarios)

Also, correcting SEGFAULT upon termination (when apps was destroyed
after ccnx stack)

Correcting LongestPrefixMatch to be able to perform default match
diff --git a/apps/ccnx-app.cc b/apps/ccnx-app.cc
index 7b9c2b9..afdf9de 100644
--- a/apps/ccnx-app.cc
+++ b/apps/ccnx-app.cc
@@ -55,7 +55,6 @@
     
 CcnxApp::~CcnxApp ()
 {
-  StopApplication ();
 }
 
 void
@@ -63,7 +62,9 @@
 {
   NS_LOG_FUNCTION_NOARGS ();
 
-  StopApplication ();
+  // Unfortunately, this causes SEGFAULT
+  // The best reason I see is that apps are freed after ccnx stack is removed
+  // StopApplication ();  
   Application::DoDispose ();
 }
 
diff --git a/examples/abilene-topology.cc b/examples/abilene-topology.cc
index 99521c6..3e7f24e 100644
--- a/examples/abilene-topology.cc
+++ b/examples/abilene-topology.cc
@@ -25,6 +25,7 @@
 #include "ns3/NDNabstraction-module.h"
 #include "ns3/point-to-point-grid.h"
 #include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/animation-interface.h"
 
 #include <iostream>
 #include <sstream>
@@ -35,6 +36,29 @@
 
 NS_LOG_COMPONENT_DEFINE ("CcnxAbileneTopology");
 
+void PrintTime ()
+{
+  NS_LOG_INFO (Simulator::Now ());
+
+  Simulator::Schedule (Seconds (10.0), PrintTime);
+}
+
+void PrintFIBs ()
+{
+  NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
+  Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
+  for (NodeList::Iterator node = NodeList::Begin ();
+       node != NodeList::End ();
+       node++)
+    {
+      // *routingStream->GetStream () << "Node " << (*node)->GetId () << "\n";
+
+      Ptr<CcnxFib> fib = (*node)->GetObject<CcnxFib> ();
+      NS_ASSERT_MSG (fib != 0, "Fire alarm");
+      *routingStream->GetStream () << *fib << "\n\n";
+    }
+}
+
 int 
 main (int argc, char *argv[])
 {
@@ -55,7 +79,7 @@
   // -- Read topology data.
   // --------------------------------------------
     
-  AnnotatedTopologyReader reader;
+  AnnotatedTopologyReader reader ("/abilene");
   reader.SetFileName (input);
   reader.SetBoundingBox (100.0, 100.0, 400.0, 400.0);
   
@@ -73,15 +97,32 @@
   // Install CCNx stack
   NS_LOG_INFO ("Installing CCNx stack");
   CcnxStackHelper ccnxHelper;
-  // ccnxHelper.SetForwardingStrategy (strategy);
-  ccnxHelper.EnableLimits (true, Seconds(0.1));
+  ccnxHelper.SetForwardingStrategy (strategy);
+  ccnxHelper.EnableLimits (false, Seconds(0.1));
+  ccnxHelper.SetDefaultRoutes (true);
   ccnxHelper.InstallAll ();
     
-  // NS_LOG_INFO ("Installing Applications");
-  // CcnxConsumerHelper consumerHelper ("preved");
-  // ApplicationContainer consumers = consumerHelper.Install (nc[0]);
-    
+  NS_LOG_INFO ("Installing Applications");
+  CcnxConsumerHelper consumerHelper ("tralala");
+  ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/abilene", "1"));
+
+  CcnxProducerHelper producerHelper ("tralala",1024);
+  ApplicationContainer producers = producerHelper.Install (Names::Find<Node> ("/abilene", "6"));
+  
+  // Simulator::Schedule (Seconds (1.0), PrintFIBs);
+  PrintFIBs ();
+
+  Simulator::Schedule (Seconds (10.0), PrintTime);
+
   Simulator::Stop (finishTime);
+
+  AnimationInterface *anim = 0;
+  if (animationFile != "")
+    {
+      anim = new AnimationInterface (animationFile);
+      anim->SetMobilityPollInterval (Seconds (1));
+    }
+
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
   Simulator::Destroy ();
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index d9f9d6b..074bdde 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -126,6 +126,8 @@
 
     
 CcnxStackHelper::CcnxStackHelper ()
+  : m_limitsEnabled (false)
+  , m_needSetDefaultRoutes (false)
 {
   m_strategyFactory.SetTypeId ("ns3::CcnxFloodingStrategy");
 }
@@ -140,6 +142,14 @@
   m_strategyFactory.SetTypeId (strategy);
 }
 
+
+void
+CcnxStackHelper::SetDefaultRoutes (bool needSet)
+{
+  NS_LOG_FUNCTION (this << needSet);
+  m_needSetDefaultRoutes = needSet;
+}
+
 void
 CcnxStackHelper::EnableLimits (bool enable/* = true*/, Time avgRtt/*=Seconds(0.1)*/, uint32_t avgContentObject/*=1100*/, uint32_t avgInterest/*=40*/)
 {
@@ -197,9 +207,15 @@
 
       Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node, device);
 
-      uint32_t __attribute__ ((unused)) face_id = ccnx->AddFace (face);
-      NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << face_id);
+      ccnx->AddFace (face);
+      NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << *face);
 
+      if (m_needSetDefaultRoutes)
+        {
+          // default route with lowest priority possible
+          AddRoute (node, "/", face, std::numeric_limits<int32_t>::max ()); 
+        }
+      
       if (m_limitsEnabled)
         {
           NS_LOG_INFO ("Limits are enabled");
@@ -242,8 +258,10 @@
 
 
 void
-CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric)
+CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const
 {
+  NS_LOG_LOGIC ("[" << node->GetId () << "]$ route add " << prefix << " via " << *face << " metric " << metric);
+
   Ptr<CcnxFib>  fib  = node->GetObject<CcnxFib> ();
 
   CcnxNameComponentsValue prefixValue;
@@ -252,10 +270,8 @@
 }
 
 void
-CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric)
+CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const
 {
-  NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
-  
   Ptr<Node> node = Names::Find<Node> (nodeName);
   NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
   
@@ -267,6 +283,7 @@
 
   AddRoute (node, prefix, face, metric);
 }
+
 /*
   void
   CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index ee166fc..bcfab3f 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -156,7 +156,7 @@
    * \param metric Routing metric
    */
   void
-  AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric);
+  AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const;
 
   /**
    * \brief Add forwarding entry in FIB
@@ -167,8 +167,13 @@
    * \param metric Routing metric
    */
   void
-  AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric);
-  
+  AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const;
+
+  /**
+   * \brief Set flag indicating necessity to install default routes in FIB
+   */
+  void
+  SetDefaultRoutes (bool needSet);
 
   /**
    * \brief Install fake IPv4 routes that could be used to find nexthops for CCNx routes
@@ -207,6 +212,7 @@
   Time     m_avgRtt;
   uint32_t m_avgContentObjectSize;
   uint32_t m_avgInterestSize;
+  bool m_needSetDefaultRoutes;
   
   // /**
   //  * @brief Enable pcap output the indicated Ccnx and interface pair.
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index 0df2ded..89e5231 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -182,7 +182,7 @@
 {
   const CcnxNameComponents &name = interest.GetName ();
   for (size_t componentsCount = name.GetComponents ().size ();
-       componentsCount > 0;
+       componentsCount >= 0;
        componentsCount--)
     {
       CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 17dc335..49031c7 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -176,7 +176,7 @@
   face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
 
   // just to be on a safe side. Do the process in two steps
-  std::list<CcnxPitEntryContainer::type::iterator> entriesToRemoves; 
+  std::list<boost::reference_wrapper<const CcnxPitEntry> > entriesToRemoves;
   BOOST_FOREACH (const CcnxPitEntry &pitEntry, *m_pit)
     {
       m_pit->modify (m_pit->iterator_to (pitEntry),
@@ -187,12 +187,12 @@
       if (pitEntry.m_fibEntry.m_faces.size () == 1 &&
           pitEntry.m_fibEntry.m_faces.begin ()->m_face == face)
         {
-          entriesToRemoves.push_back (m_pit->iterator_to (pitEntry));
+          entriesToRemoves.push_back (boost::cref (pitEntry));
         }
     }
-  BOOST_FOREACH (CcnxPitEntryContainer::type::iterator entry, entriesToRemoves)
+  BOOST_FOREACH (const CcnxPitEntry &removedEntry, entriesToRemoves)
     {
-      m_pit->erase (entry);
+      m_pit->erase (m_pit->iterator_to (removedEntry));
     }
 
   CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
diff --git a/model/ccnx-name-components.cc b/model/ccnx-name-components.cc
index b551733..a7066de 100644
--- a/model/ccnx-name-components.cc
+++ b/model/ccnx-name-components.cc
@@ -58,7 +58,7 @@
 std::list<boost::reference_wrapper<const std::string> >
 CcnxNameComponents::GetSubComponents (size_t num) const
 {
-  NS_ASSERT_MSG (1<=num && num<=m_prefix.size (), "Invalid number of subcomponents requested");
+  NS_ASSERT_MSG (0<=num && num<=m_prefix.size (), "Invalid number of subcomponents requested");
   
   std::list<boost::reference_wrapper<const std::string> > subComponents;
   std::list<std::string>::const_iterator component = m_prefix.begin();