Several important corrections. Adding option to delay data at every node (random from 0.1 to 2 ms)
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index e8b0fc1..c06e0cf 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -32,6 +32,7 @@
#include "ns3/boolean.h"
#include "ns3/string.h"
#include "ns3/simulator.h"
+#include "ns3/random-variable.h"
#include "ns3/ccnx-header-helper.h"
@@ -83,6 +84,10 @@
BooleanValue (false),
MakeBooleanAccessor (&CcnxL3Protocol::m_cacheUnsolicitedData),
MakeBooleanChecker ())
+ .AddAttribute ("RandomDataDelaying", "Delaying data processing",
+ BooleanValue (false),
+ MakeBooleanAccessor (&CcnxL3Protocol::m_delayingDataProcessing),
+ MakeBooleanChecker ())
;
return tid;
}
@@ -392,8 +397,9 @@
Ptr<CcnxInterestHeader> &header,
const Ptr<const Packet> &packet)
{
- NS_LOG_FUNCTION (incomingFace << header << packet);
+ NS_LOG_FUNCTION (incomingFace << header << packet << header->GetName ());
m_inInterests (header, incomingFace);
+ // NS_LOG_DEBUG (*m_pit);
// Lookup of Pit (and associated Fib) entry for this Interest
tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
@@ -532,6 +538,55 @@
}
}
+void
+CcnxL3Protocol::OnDataDelayed (Ptr<CcnxContentObjectHeader> header,
+ Ptr<Packet> payload,
+ const Ptr<const Packet> &packet)
+{
+ if (m_delayingDataProcessing)
+ {
+ NS_LOG_DEBUG ("Delayed processing " << header->GetName ());
+ // NS_LOG_DEBUG (*m_pit);
+ }
+
+ // 1. Lookup PIT entry
+ try
+ {
+ CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header);
+
+ //satisfy all pending incoming Interests
+ BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->m_incoming)
+ {
+ incoming.m_face->Send (packet->Copy ());
+ m_outData (header, payload, false, incoming.m_face);
+ NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
+
+ // successfull forwarded data trace
+ }
+
+ if (pitEntry->m_incoming.size () > 0)
+ {
+ // All incoming interests are satisfied. Remove them
+ m_pit->modify (pitEntry,
+ ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
+
+ // Remove all outgoing faces
+ m_pit->modify (pitEntry,
+ ll::bind (&CcnxPitEntry::ClearOutgoing, ll::_1));
+
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (pitEntry,
+ ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ }
+ }
+ catch (CcnxPitEntryNotFound)
+ {
+ NS_LOG_DEBUG ("Pit entry not found (was satisfied and removed before)");
+ return; // do not process unsoliced data packets
+ }
+}
+
// Processing ContentObjects
void
CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
@@ -542,20 +597,21 @@
NS_LOG_FUNCTION (incomingFace << header->GetName () << payload << packet);
m_inData (header, payload, incomingFace);
-
+ // NS_LOG_DEBUG (*m_pit);
+
// 1. Lookup PIT entry
try
{
- const CcnxPitEntry &pitEntry = m_pit->Lookup (*header);
+ CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header);
// Note that with MultiIndex we need to modify entries indirectly
- CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry.m_outgoing.find (incomingFace);
+ CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry->m_outgoing.find (incomingFace);
// If we have sent interest for this data via this face, then update stats.
- if (out != pitEntry.m_outgoing.end ())
+ if (out != pitEntry->m_outgoing.end ())
{
- m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry.m_fibEntry),
+ m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry->m_fibEntry),
ll::bind (&CcnxFibEntry::UpdateFaceRtt,
ll::_1,
incomingFace,
@@ -582,37 +638,37 @@
}
// Update metric status for the incoming interface in the corresponding FIB entry
- m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry.m_fibEntry),
+ m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry->m_fibEntry),
ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
// Add or update entry in the content store
m_contentStore->Add (header, payload);
- //satisfy all pending incoming Interests
- BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
+ m_pit->modify (pitEntry,
+ ll::bind (&CcnxPitEntry::RemoveIncoming, ll::_1, incomingFace));
+
+ if (pitEntry->m_incoming.size () == 0)
{
- if (incoming.m_face != incomingFace)
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (pitEntry,
+ ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ }
+ else
+ {
+ if (!m_delayingDataProcessing)
{
- incoming.m_face->Send (packet->Copy ());
- m_outData (header, payload, false, incoming.m_face);
- NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
+ OnDataDelayed (header, payload, packet);
}
else
{
- NS_LOG_DEBUG ("Ignore incoming interests from ourselves (" << *incoming.m_face << ")");
+ NS_LOG_DEBUG ("Delaying Data forwarding " << header->GetName ());
+ UniformVariable delay (0.0001, 0.002);
+ Simulator::Schedule (Seconds (delay.GetValue ()),
+ &CcnxL3Protocol::OnDataDelayed, this, header, payload, packet);
}
-
- // successfull forwarded data trace
}
- // All incoming interests are satisfied. Remove them
- m_pit->modify (m_pit->iterator_to (pitEntry),
- ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
-
- // Set pruning timout on PIT entry (instead of deleting the record)
- m_pit->modify (m_pit->iterator_to (pitEntry),
- ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
- Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
}
catch (CcnxPitEntryNotFound)
{
@@ -639,6 +695,7 @@
Ptr<CcnxInterestHeader> header)
{
NS_LOG_FUNCTION (this << &pitEntry);
+ // NS_LOG_DEBUG (*m_pit);
if (m_nacksEnabled)
{
Ptr<Packet> packet = Create<Packet> ();
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index ba4fcaa..a9c4f8a 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -195,6 +195,11 @@
GiveUpInterest (const CcnxPitEntry &pitEntry,
Ptr<CcnxInterestHeader> header);
+ void
+ OnDataDelayed (Ptr<CcnxContentObjectHeader> header,
+ Ptr<Packet> payload,
+ const Ptr<const Packet> &packet);
+
private:
uint32_t m_faceCounter; ///< \brief counter of faces. Increased every time a new face is added to the stack
typedef std::vector<Ptr<CcnxFace> > CcnxFaceList;
@@ -210,6 +215,7 @@
bool m_nacksEnabled;
bool m_cacheUnsolicitedData;
+ bool m_delayingDataProcessing;
// Time m_bucketLeakInterval;
// EventId m_bucketLeakEvent;
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index b9cd3f5..d0615b0 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -49,7 +49,7 @@
void
CcnxPitEntry::SetExpireTime (const Time &expireTime)
{
- NS_LOG_FUNCTION (expireTime);
+ NS_LOG_FUNCTION (expireTime.ToDouble (Time::S));
m_expireTime = expireTime;
}
@@ -57,11 +57,13 @@
void
CcnxPitEntry::UpdateLifetime (const Time &offsetTime)
{
+ NS_LOG_FUNCTION (offsetTime.ToDouble (Time::S));
+
Time newExpireTime = Simulator::Now () + offsetTime;
if (newExpireTime > m_expireTime)
m_expireTime = newExpireTime;
- NS_LOG_DEBUG ("Updated lifetime to " << m_expireTime.ToDouble (Time::S));
+ NS_LOG_INFO ("Updated lifetime to " << m_expireTime.ToDouble (Time::S));
}
CcnxPitEntryIncomingFaceContainer::type::iterator
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index ead991c..a68c4a7 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -140,7 +140,7 @@
m_fib = fib;
}
-const CcnxPitEntry&
+CcnxPitEntryContainer::type::iterator
CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
{
// NS_LOG_FUNCTION_NOARGS ();
@@ -157,19 +157,16 @@
entry = get<i_prefix> ().find (subPrefix);
if (entry != end())
- return *entry;
+ return entry;
}
- if (entry == end ())
- throw CcnxPitEntryNotFound();
-
- return *entry;
+ throw CcnxPitEntryNotFound();
}
boost::tuple<const CcnxPitEntry&, bool, bool>
CcnxPit::Lookup (const CcnxInterestHeader &header)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (header.GetName ());
NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
bool isDuplicate = false;
@@ -195,7 +192,17 @@
}
else
{
- isNew = false;
+ NS_LOG_INFO ("ExpireTime: " << entry->m_expireTime.ToDouble (Time::S));
+ if (entry->m_expireTime - Simulator::Now () < MilliSeconds (10))
+ {
+ modify (entry,
+ boost::bind(&CcnxPitEntry::ClearIncoming, boost::lambda::_1));
+
+ modify (entry,
+ boost::bind(&CcnxPitEntry::ClearOutgoing, boost::lambda::_1));
+ }
+
+ isNew = entry->m_incoming.size () == 0 && entry->m_outgoing.size () == 0; // entry was preserved to detect loops, but technically removed
isDuplicate = entry->IsNonceSeen (header.GetNonce ());
}
@@ -212,7 +219,7 @@
{
BOOST_FOREACH (const CcnxPitEntry &entry, pit)
{
- os << entry;
+ os << entry << std::endl;
}
return os;
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index 70347e4..0638fa9 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -123,7 +123,7 @@
* \returns const reference to Pit entry. If record not found,
* CcnxPitEntryNotFound exception will be thrown
*/
- const CcnxPitEntry&
+ CcnxPitEntryContainer::type::iterator
Lookup (const CcnxContentObjectHeader &header) const;
/**