Checkpoint. Some changes in forwarding strategy API
Removing WillSendOutInterest and adding TrySendOutInterests, which
should be fully defined in child classes (or fully used from parent, but
not combined).
diff --git a/model/fw/best-route.cc b/model/fw/best-route.cc
index a034e1e..604318f 100644
--- a/model/fw/best-route.cc
+++ b/model/fw/best-route.cc
@@ -57,42 +57,31 @@
}
bool
-BestRoute::DoPropagateInterest (Ptr<Face> incomingFace,
+BestRoute::DoPropagateInterest (Ptr<Face> inFace,
Ptr<const InterestHeader> header,
Ptr<const Packet> origPacket,
Ptr<pit::Entry> pitEntry)
{
NS_LOG_FUNCTION (this);
-
// Try to work out with just green faces
- bool greenOk = super::DoPropagateInterest (incomingFace, header, origPacket, pitEntry);
+ bool greenOk = super::DoPropagateInterest (inFace, header, origPacket, pitEntry);
if (greenOk)
return true;
int propagatedCount = 0;
+
BOOST_FOREACH (const fib::FaceMetric &metricFace, pitEntry->GetFibEntry ()->m_faces.get<fib::i_metric> ())
{
+ NS_LOG_DEBUG ("Trying " << boost::cref(metricFace));
if (metricFace.m_status == fib::FaceMetric::NDN_FIB_RED) // all non-read faces are in front
break;
-
- if (metricFace.m_face == incomingFace)
- continue; // same face as incoming, don't forward
- if (pitEntry->GetIncoming ().find (metricFace.m_face) != pitEntry->GetIncoming ().end ())
- continue; // don't forward to face that we received interest from
-
- if (!WillSendOutInterest (metricFace.m_face, header, pitEntry))
+ if (!TrySendOutInterest (inFace, metricFace.m_face, header, origPacket, pitEntry))
{
continue;
}
- //transmission
- Ptr<Packet> packetToSend = origPacket->Copy ();
- metricFace.m_face->Send (packetToSend);
-
- DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
-
propagatedCount++;
break; // do only once
}
diff --git a/model/fw/flooding.cc b/model/fw/flooding.cc
index 8c43c52..6d021ec 100644
--- a/model/fw/flooding.cc
+++ b/model/fw/flooding.cc
@@ -74,22 +74,10 @@
if (metricFace.m_status == fib::FaceMetric::NDN_FIB_RED) // all non-read faces are in the front of the list
break;
- if (metricFace.m_face == inFace)
- {
- NS_LOG_DEBUG ("continue (same as incoming)");
- continue; // same face as incoming, don't forward
- }
-
- if (!WillSendOutInterest (metricFace.m_face, header, pitEntry))
+ if (!TrySendOutInterest (inFace, metricFace.m_face, header, origPacket, pitEntry))
{
continue;
}
-
- //transmission
- Ptr<Packet> packetToSend = origPacket->Copy ();
- metricFace.m_face->Send (packetToSend);
-
- DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
propagatedCount++;
}
diff --git a/model/fw/green-yellow-red.cc b/model/fw/green-yellow-red.cc
index f13b29b..6611c13 100644
--- a/model/fw/green-yellow-red.cc
+++ b/model/fw/green-yellow-red.cc
@@ -79,19 +79,10 @@
metricFace.m_status == fib::FaceMetric::NDN_FIB_YELLOW)
break; //propagate only to green faces
- if (pitEntry->GetIncoming ().find (metricFace.m_face) != pitEntry->GetIncoming ().end ())
- continue; // don't forward to face that we received interest from
-
- if (!WillSendOutInterest (metricFace.m_face, header, pitEntry))
+ if (!TrySendOutInterest (inFace, metricFace.m_face, header, origPacket, pitEntry))
{
continue;
}
-
- //transmission
- Ptr<Packet> packetToSend = origPacket->Copy ();
- metricFace.m_face->Send (packetToSend);
-
- DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
propagatedCount++;
break; // propagate only one interest
diff --git a/model/fw/ndn-forwarding-strategy.cc b/model/fw/ndn-forwarding-strategy.cc
index 6348424..4219deb 100644
--- a/model/fw/ndn-forwarding-strategy.cc
+++ b/model/fw/ndn-forwarding-strategy.cc
@@ -443,21 +443,40 @@
}
bool
-ForwardingStrategy::WillSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::TrySendOutInterest (Ptr<Face> inFace,
+ Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry)
{
+ if (outFace == inFace)
+ {
+ NS_LOG_DEBUG ("Same as incoming");
+ return false; // same face as incoming, don't forward
+ }
+
pit::Entry::out_iterator outgoing =
pitEntry->GetOutgoing ().find (outFace);
-
- if (outgoing != pitEntry->GetOutgoing ().end () &&
- outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
- {
- NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount ());
- return false; // already forwarded before during this retransmission cycle
- }
+ if (outgoing != pitEntry->GetOutgoing ().end ())
+ {
+ if (!m_detectRetransmissions)
+ return false; // suppress
+ else if (outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
+ {
+ NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount ());
+ return false; // already forwarded before during this retransmission cycle
+ }
+ }
+
pitEntry->AddOutgoing (outFace);
+
+ //transmission
+ Ptr<Packet> packetToSend = origPacket->Copy ();
+ outFace->Send (packetToSend);
+
+ DidSendOutInterest (outFace, header, origPacket, pitEntry);
+
return true;
}
diff --git a/model/fw/ndn-forwarding-strategy.h b/model/fw/ndn-forwarding-strategy.h
index 65de9b8..f164d7f 100644
--- a/model/fw/ndn-forwarding-strategy.h
+++ b/model/fw/ndn-forwarding-strategy.h
@@ -167,9 +167,11 @@
* If event returns false, then there is some kind of a problem (e.g., per-face limit reached)
*/
virtual bool
- WillSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<pit::Entry> pitEntry);
+ TrySendOutInterest (Ptr<Face> inFace,
+ Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry);
/**
* @brief Event fired just after sending out an interest
diff --git a/model/fw/per-fib-limits.cc b/model/fw/per-fib-limits.cc
index a8fc46a..df4607d 100644
--- a/model/fw/per-fib-limits.cc
+++ b/model/fw/per-fib-limits.cc
@@ -16,7 +16,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- * Ilya Moiseenko <iliamo@cs.ucla.edu>
*/
#include "per-fib-limits.h"
@@ -52,16 +51,6 @@
.SetGroupName ("Ndn")
.SetParent <super> ()
.AddConstructor <PerFibLimits> ()
-
- .AddAttribute ("Threshold", "Minimum number of incoming interests to enable dropping decision",
- DoubleValue (0.25),
- MakeDoubleAccessor (&PerFibLimits::m_threshold),
- MakeDoubleChecker<double> ())
-
- .AddAttribute ("GraceAcceptProbability", "Probability to accept Interest even though stats telling that satisfaction ratio is 0",
- DoubleValue (0.01),
- MakeDoubleAccessor (&PerFibLimits::m_graceAcceptProbability),
- MakeDoubleChecker<double> ())
;
return tid;
}
@@ -74,63 +63,101 @@
PerFibLimits::DoDispose ()
{
super::DoDispose ();
- m_decayLimitsEvent.Cancel ();
+ // m_decayLimitsEvent.Cancel ();
}
+void
+PerFibLimits::RemoveFace (Ptr<Face> face)
+{
+ super::RemoveFace (face);
+
+ for (PitQueueMap::iterator item = m_pitQueues.begin ();
+ item != m_pitQueues.end ();
+ item ++)
+ {
+ item->second.Remove (face);
+ }
+ m_pitQueues.erase (face);
+}
+
+
bool
-PerFibLimits::WillSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<pit::Entry> pitEntry)
+PerFibLimits::TrySendOutInterest (Ptr<Face> inFace,
+ Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry)
{
NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
- // override all (if any) parent processing
+ // totally override all (if any) parent processing
pit::Entry::out_iterator outgoing =
pitEntry->GetOutgoing ().find (outFace);
if (outgoing != pitEntry->GetOutgoing ().end ())
{
+ // just suppress without any other action
return false;
}
- if (pitEntry->GetFibEntry ()->GetLimits ().IsBelowLimit ())
+ // if (pitEntry->GetFibEntry ()->GetLimits ().IsBelowLimit ())
+ // {
+ // if (outFace->GetLimits ().IsBelowLimit ())
+ // {
+ // pitEntry->AddOutgoing (outFace);
+ // return true;
+ // }
+ // else
+ // {
+ // NS_LOG_DEBUG ("Face limit. Reverting back per-prefix allowance");
+ // pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
+ // }
+ // }
+
+ if (outFace->GetLimits ().IsBelowLimit ())
{
- if (outFace->GetLimits ().IsBelowLimit ())
- {
- pitEntry->AddOutgoing (outFace);
- return true;
- }
- else
- {
- NS_LOG_DEBUG ("Face limit. Reverting back per-prefix allowance");
- pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
- }
+ pitEntry->AddOutgoing (outFace);
+
+ //transmission
+ Ptr<Packet> packetToSend = origPacket->Copy ();
+ outFace->Send (packetToSend);
+
+ DidSendOutInterest (outFace, header, origPacket, pitEntry);
+
+ return true;
+ }
+ else
+ {
+ NS_LOG_DEBUG ("Face limit");
}
- return false;
+ bool enqueued = m_pitQueues[outFace].Enqueue (inFace, pitEntry);
+ if (enqueued)
+ {
+ NS_LOG_DEBUG ("PIT entry is enqueued for delayed processing. Telling that we forwarding possible");
+ return true;
+ }
+ else
+ return false;
}
void
PerFibLimits::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
{
NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
+ super::WillEraseTimedOutPendingInterest (pitEntry);
+ PitQueue::Remove (pitEntry);
+
for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
face != pitEntry->GetOutgoing ().end ();
face ++)
{
face->m_face->GetLimits ().RemoveOutstanding ();
- // face->m_face->GetLimits ()->DecreaseLimit (); !!! do not decrease per-face limit. it doesn't make sense !!!
}
-
- pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
- // pitEntry->GetFibEntry ()->GetLimits ().DecreaseLimit (); // multiplicative decrease
- if (!m_decayLimitsEvent.IsRunning ())
- {
- UniformVariable rand (0,5);
- m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0) + Seconds (0.001 * rand.GetValue ()), &PerFibLimits::DecayLimits, this);
- }
+ ProcessFromQueue ();
+ // pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
}
@@ -139,22 +166,44 @@
Ptr<pit::Entry> pitEntry)
{
NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
-
super::WillSatisfyPendingInterest (inFace, pitEntry);
+
+ PitQueue::Remove (pitEntry);
for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
face != pitEntry->GetOutgoing ().end ();
face ++)
{
face->m_face->GetLimits ().RemoveOutstanding ();
- // face->m_face->GetLimits ()->IncreaseLimit (); !!! do not increase (as do not decrease) per-face limit. again, it doesn't make sense
}
+
+ ProcessFromQueue ();
- pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
- // pitEntry->GetFibEntry ()->GetLimits ().IncreaseLimit (); // additive increase
+ // pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
}
+void
+PerFibLimits::ProcessFromQueue ()
+{
+ for (PitQueueMap::iterator queue = m_pitQueues.begin ();
+ queue != m_pitQueues.end ();
+ queue++)
+ {
+ if (queue->second.IsEmpty ())
+ continue;
+
+ // if (outFace->GetLimits ().IsBelowLimit ())
+ // {
+ // pitEntry->AddOutgoing (outFace);
+ // }
+ // else
+ // {
+ // // do nothing
+ // }
+ }
+}
+
// void
// PerFibLimits::DidReceiveValidNack (Ptr<Face> inFace,
// uint32_t nackCode,
@@ -165,18 +214,18 @@
// // ??
// }
-void
-PerFibLimits::DecayLimits ()
-{
- for (Ptr<fib::Entry> entry = m_fib->Begin ();
- entry != m_fib->End ();
- entry = m_fib->Next (entry))
- {
- entry->GetLimits ().DecayCurrentLimit ();
- }
+// void
+// PerFibLimits::DecayLimits ()
+// {
+// for (Ptr<fib::Entry> entry = m_fib->Begin ();
+// entry != m_fib->End ();
+// entry = m_fib->Next (entry))
+// {
+// entry->GetLimits ().DecayCurrentLimit ();
+// }
- m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0), &PerFibLimits::DecayLimits, this);
-}
+// m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0), &PerFibLimits::DecayLimits, this);
+// }
} // namespace fw
diff --git a/model/fw/per-fib-limits.h b/model/fw/per-fib-limits.h
index ddd23f3..3f23992 100644
--- a/model/fw/per-fib-limits.h
+++ b/model/fw/per-fib-limits.h
@@ -25,6 +25,7 @@
#include "ns3/event-id.h"
#include "fw-stats.h"
+#include "../../utils/ndn-pit-queue.h"
namespace ns3 {
namespace ndn {
@@ -52,29 +53,32 @@
virtual void
WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry);
+ virtual void
+ RemoveFace (Ptr<Face> face);
+
protected:
virtual bool
- WillSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<pit::Entry> pitEntry);
+ TrySendOutInterest (Ptr<Face> inFace,
+ Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry);
virtual void
WillSatisfyPendingInterest (Ptr<Face> inFace,
Ptr<pit::Entry> pitEntry);
+private:
+ void
+ ProcessFromQueue ();
+
// from Object
void
DoDispose ();
-
+
private:
- void
- DecayLimits ();
-
-private:
- EventId m_decayLimitsEvent;
-
- double m_threshold;
- double m_graceAcceptProbability;
+ typedef std::map< Ptr<Face>, PitQueue > PitQueueMap;
+ PitQueueMap m_pitQueues; // per-outgoing face pit queue
};
diff --git a/model/fw/smart-flooding.cc b/model/fw/smart-flooding.cc
index 4ca0fd1..e74b612 100644
--- a/model/fw/smart-flooding.cc
+++ b/model/fw/smart-flooding.cc
@@ -79,22 +79,10 @@
if (metricFace.m_status == fib::FaceMetric::NDN_FIB_RED) // all non-read faces are in the front of the list
break;
- if (metricFace.m_face == inFace)
- {
- NS_LOG_DEBUG ("continue (same as incoming)");
- continue; // same face as incoming, don't forward
- }
-
- if (!WillSendOutInterest (metricFace.m_face, header, pitEntry))
+ if (!TrySendOutInterest (inFace, metricFace.m_face, header, origPacket, pitEntry))
{
continue;
}
-
- //transmission
- Ptr<Packet> packetToSend = origPacket->Copy ();
- metricFace.m_face->Send (packetToSend);
-
- DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
propagatedCount++;
}
diff --git a/model/fw/stats-based-randomized-interest-accept.cc b/model/fw/stats-based-randomized-interest-accept.cc
index f83604d..a159801 100644
--- a/model/fw/stats-based-randomized-interest-accept.cc
+++ b/model/fw/stats-based-randomized-interest-accept.cc
@@ -76,9 +76,11 @@
}
bool
-StatsBasedRandomizedInterestAccept::WillSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<pit::Entry> pitEntry)
+StatsBasedRandomizedInterestAccept::TrySendOutInterest (Ptr<Face> inFace,
+ Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry)
{
NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
// override all (if any) parent processing
@@ -91,8 +93,6 @@
return false;
}
- // check stats
- Ptr<Face> inFace = pitEntry->GetIncoming ().begin ()->m_face;
// const ndnSIM::LoadStatsFace &stats = GetStatsTree ()[header->GetName ()].incoming ().find (inFace)->second;
const ndnSIM::LoadStatsFace &stats = GetStatsTree ()["/"].incoming ().find (inFace)->second;
@@ -118,6 +118,13 @@
if (outFace->GetLimits ().IsBelowLimit ())
{
pitEntry->AddOutgoing (outFace);
+
+ //transmission
+ Ptr<Packet> packetToSend = origPacket->Copy ();
+ outFace->Send (packetToSend);
+
+ DidSendOutInterest (outFace, header, origPacket, pitEntry);
+
return true;
}
else
diff --git a/model/fw/stats-based-randomized-interest-accept.h b/model/fw/stats-based-randomized-interest-accept.h
index 7ce0e9c..4fb833e 100644
--- a/model/fw/stats-based-randomized-interest-accept.h
+++ b/model/fw/stats-based-randomized-interest-accept.h
@@ -59,9 +59,11 @@
protected:
virtual bool
- WillSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<pit::Entry> pitEntry);
+ TrySendOutInterest (Ptr<Face> inFace,
+ Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry);
virtual void
WillSatisfyPendingInterest (Ptr<Face> inFace,
diff --git a/utils/ndn-pit-queue.cc b/utils/ndn-pit-queue.cc
index 29551a8..b287308 100644
--- a/utils/ndn-pit-queue.cc
+++ b/utils/ndn-pit-queue.cc
@@ -154,6 +154,21 @@
tag->RemoveFromAllQueues ();
}
+bool
+PitQueue::IsEmpty () const
+{
+ bool isEmpty = (m_queues.size () == 0);
+
+ for (PerInFaceQueue::const_iterator queue = m_queues.begin ();
+ queue != m_queues.end ();
+ queue ++)
+ {
+ isEmpty &= (queue->second->size () == 0);
+ }
+
+ return isEmpty;
+}
+
void
fw::PitQueueTag::InsertQueue (boost::shared_ptr<PitQueue::Queue> queue, PitQueue::Queue::iterator iterator)
{
diff --git a/utils/ndn-pit-queue.h b/utils/ndn-pit-queue.h
index ff4f0de..aad6820 100644
--- a/utils/ndn-pit-queue.h
+++ b/utils/ndn-pit-queue.h
@@ -37,31 +37,73 @@
class Face;
namespace pit { class Entry; }
+/**
+ * @ingroup ndn
+ * @brief Queue for PIT entries, interests for which cannot be immediately forwarded
+ */
class PitQueue
{
public:
+ /**
+ * @brief Default constructor
+ */
PitQueue ();
-
+
+ /**
+ * @brief Set maximum queue size
+ * @param size per-incoming face maximum queue size
+ *
+ * Each per-incoming-face queue will have this maximum size
+ */
void
SetMaxQueueSize (uint32_t size);
+ /**
+ * @brief Get current maximum queue size
+ * @returns per-incoming face maximum queue size
+ */
uint32_t
GetMaxQueueSize () const;
+ /**
+ * @brief Enqueue PIT entry for delayed processing
+ * @param inFace incoming face to which queue PIT entry should enqueued
+ * @param pitEntry smart pointer to PIT entry
+ * return true if successfully enqueued, false if limit is reached or some other reason
+ */
bool
Enqueue (Ptr<Face> inFace,
Ptr<pit::Entry> pitEntry);
+ /**
+ * @brief Get next PIT entry
+ * @returns next PIT entry or 0 if no entries available
+ *
+ * This method implement round-robin (in future weighted round-robin) to pick elements from different per-in-face queues
+ */
Ptr<pit::Entry>
Pop ();
- // cleanup procedures
+ /**
+ * @brief Remove all references to face from all queues and enqueued PIT entries
+ * @param face smart pointer to face
+ */
void
Remove (Ptr<Face> face);
- void
+ /**
+ * @brief Remove all references to PIT entry from queues
+ * @param entry smart pointer to PIT entry
+ */
+ static void
Remove (Ptr<pit::Entry> entry);
+ /**
+ * @brief Check if queue is empty
+ */
+ bool
+ IsEmpty () const;
+
public:
typedef std::list< Ptr<pit::Entry> > Queue;
typedef std::map< Ptr<Face>, boost::shared_ptr<Queue> > PerInFaceQueue;
@@ -74,6 +116,10 @@
namespace fw {
+/**
+ * @ingroup ndn
+ * @brief Forwarding strategy tag that stores queue-related information in PIT entries
+ */
class PitQueueTag :
public Tag
{
@@ -82,15 +128,30 @@
typedef std::map< boost::shared_ptr<PitQueue::Queue>, PitQueue::Queue::iterator > MapOfItems;
public:
+ /**
+ * @brief Virtual destructor
+ */
virtual
~PitQueueTag () { };
+ /**
+ * @brief Remember in which queue at which position PIT entry is enqueued
+ * @brief item smart pointer to Queue
+ * @brief iterator queue's iterator
+ */
void
InsertQueue (boost::shared_ptr<PitQueue::Queue> item, PitQueue::Queue::iterator iterator);
-
+
+ /**
+ * @brief Remove PIT entry from all queues
+ */
void
RemoveFromAllQueues ();
+ /**
+ * @brief Remove PIT entry from the specified queue
+ * @param queue Queue from which PIT entry should be removed
+ */
void
RemoveFromQueue (boost::shared_ptr<PitQueue::Queue> queue);