model: Add ns3::ndn::Pit::MaxPitEntryLifetime to configure maximum time for which routers are willing to accept any incoming interest

Actual PIT lifetime should be minimum of MaxPitEntryLifetime and
InterestLifetime specified in the Interest packet.
diff --git a/model/pit/ndn-pit-entry.cc b/model/pit/ndn-pit-entry.cc
index f380b75..3847503 100644
--- a/model/pit/ndn-pit-entry.cc
+++ b/model/pit/ndn-pit-entry.cc
@@ -20,6 +20,7 @@
 
 #include "ndn-pit-entry.h"
 
+#include "ns3/ndn-pit.h"
 #include "ns3/ndn-fib.h"
 #include "ns3/ndn-name.h"
 #include "ns3/ndn-interest.h"
@@ -44,13 +45,15 @@
   : m_container (container)
   , m_interest (header)
   , m_fibEntry (fibEntry)
-  , m_expireTime (Simulator::Now () + (!header->GetInterestLifetime ().IsZero ()?
-                                       header->GetInterestLifetime ():
-                                       Seconds (1.0)))
   , m_maxRetxCount (0)
 {
-  NS_LOG_FUNCTION (GetPrefix () << m_expireTime);
-  // note that if interest lifetime is not set, the behavior is undefined
+  NS_LOG_FUNCTION (this);
+
+  // UpdateLifetime is (and should) be called from the forwarding strategy
+
+  // UpdateLifetime ((!header->GetInterestLifetime ().IsZero ()?
+  //                  header->GetInterestLifetime ():
+  //                  Seconds (1.0)));
 }
 
 Entry::~Entry ()
@@ -61,9 +64,11 @@
 void
 Entry::UpdateLifetime (const Time &offsetTime)
 {
-  NS_LOG_FUNCTION (offsetTime.ToDouble (Time::S));
+  NS_LOG_FUNCTION (this);
 
-  Time newExpireTime = Simulator::Now () + offsetTime;
+  Time newExpireTime = Simulator::Now () + (m_container.GetMaxPitEntryLifetime ().IsZero () ?
+                                            offsetTime :
+                                            std::min (m_container.GetMaxPitEntryLifetime (), offsetTime));
   if (newExpireTime > m_expireTime)
     m_expireTime = newExpireTime;
 
diff --git a/model/pit/ndn-pit.cc b/model/pit/ndn-pit.cc
index 224e013..ea84496 100644
--- a/model/pit/ndn-pit.cc
+++ b/model/pit/ndn-pit.cc
@@ -50,6 +50,13 @@
                    TimeValue (), // by default, PIT entries are removed instantly
                    MakeTimeAccessor (&Pit::m_PitEntryPruningTimout),
                    MakeTimeChecker ())
+
+    .AddAttribute ("MaxPitEntryLifetime",
+                   "Maximum amount of time for which a router is willing to maintain a PIT entry. "
+                   "Actual PIT lifetime should be minimum of MaxPitEntryLifetime and InterestLifetime specified in the Interest packet",
+                   TimeValue (), // by default, PIT entries are kept for the time, specified by the InterestLifetime
+                   MakeTimeAccessor (&Pit::GetMaxPitEntryLifetime, &Pit::SetMaxPitEntryLifetime),
+                   MakeTimeChecker ())
     ;
 
   return tid;
diff --git a/model/pit/ndn-pit.h b/model/pit/ndn-pit.h
index dd237c1..4c07fd2 100644
--- a/model/pit/ndn-pit.h
+++ b/model/pit/ndn-pit.h
@@ -107,7 +107,7 @@
    */
   virtual Ptr<pit::Entry>
   Create (Ptr<const Interest> header) = 0;
-  
+
   /**
    * @brief Mark PIT entry deleted
    * @param entry PIT entry
@@ -153,16 +153,30 @@
   ////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////
-  
+
   /**
    * @brief Static call to cheat python bindings
    */
   static inline Ptr<Pit>
   GetPit (Ptr<Object> node);
 
+  /**
+   * @brief Get maximum PIT entry lifetime
+   */
+  inline const Time&
+  GetMaxPitEntryLifetime () const;
+
+  /**
+   * @brief Set maximum PIT entry lifetime
+   */
+  inline void
+  SetMaxPitEntryLifetime (const Time &maxLifetime);
+
 protected:
   // configuration variables. Check implementation of GetTypeId for more details
-  Time    m_PitEntryPruningTimout;
+  Time m_PitEntryPruningTimout;
+
+  Time m_maxPitEntryLifetime;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -181,6 +195,19 @@
   return node->GetObject<Pit> ();
 }
 
+inline const Time&
+Pit::GetMaxPitEntryLifetime () const
+{
+  return m_maxPitEntryLifetime;
+}
+
+inline void
+Pit::SetMaxPitEntryLifetime (const Time &maxLifetime)
+{
+  m_maxPitEntryLifetime = maxLifetime;
+}
+
+
 } // namespace ndn
 } // namespace ns3