Correcting bugs with cleaning timeouts in PIT/RIT/ContentStore
Removing RIT concept. Instead, keep track of nonces for each PIT entry.
Many changes in CcnxL3Protocol regarding Interest/Data handling (NACK
are not yet handled at all)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!! Remove when is not actual !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code is not compiling !!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 81d44b8..ac3950c 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -23,6 +23,7 @@
#include "ns3/ccnx-local-face.h"
#include "ns3/ccnx.h"
#include "ns3/callback.h"
+#include "ns3/string.h"
#include "ns3/ccnx-content-object-header.h"
NS_LOG_COMPONENT_DEFINE ("CcnxConsumer");
@@ -39,15 +40,15 @@
.SetParent<Application> ()
.AddConstructor<CcnxConsumer> ()
.AddAttribute ("OffTime", "Time interval between packets",
- TimeValue (Seconds (0.1)),
+ StringValue ("100ms"),
MakeTimeAccessor (&CcnxConsumer::m_offTime),
MakeTimeChecker ())
.AddAttribute ("InterestName","CcnxName of the Interest (use CcnxNameComponents)",
- CcnxNameComponentsValue (),
+ StringValue ("/"),
MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_interestName),
MakeCcnxNameComponentsChecker ())
.AddAttribute ("LifeTime", "LifeTime fo interest packet",
- TimeValue (Seconds (0)),
+ StringValue ("2s"),
MakeTimeAccessor (&CcnxConsumer::m_interestLifeTime),
MakeTimeChecker ())
.AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index acf4a5f..9d6454a 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -33,6 +33,7 @@
NS_LOG_COMPONENT_DEFINE ("CcnxGrid");
uint32_t nGrid = 3;
+Time finishTime = Seconds (20.0);
void PrintTime ()
{
@@ -46,13 +47,14 @@
{
Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("1ms"));
- Config::SetDefault ("ns3::CcnxConsumer::OffTime", StringValue ("100ms"));
+ Config::SetDefault ("ns3::CcnxConsumer::OffTime", StringValue ("1ms"));
Packet::EnableChecking();
Packet::EnablePrinting();
CommandLine cmd;
cmd.AddValue ("nGrid", "Number of grid nodes", nGrid);
+ cmd.AddValue ("finish", "Finish time", finishTime);
cmd.Parse (argc, argv);
PointToPointHelper p2p;
@@ -82,8 +84,8 @@
consumerNodes.Add (grid.GetNode (0,0));
// Populate FIB based on IPv4 global routing controller
- // ccnxHelper.InstallFakeGlobalRoutes ();
- // ccnxHelper.InstallRouteTo (producer);
+ ccnxHelper.InstallFakeGlobalRoutes ();
+ ccnxHelper.InstallRouteTo (producer);
NS_LOG_INFO ("Installing Applications");
std::ostringstream prefix;
@@ -93,13 +95,13 @@
ApplicationContainer consumers = consumerHelper.Install (consumerNodes);
consumers.Start (Seconds (0.0));
- consumers.Stop (Seconds (20.0));
+ consumers.Stop (finishTime);
CcnxProducerHelper producerHelper (prefix.str (),120);
ApplicationContainer producers = producerHelper.Install (producer);
producers.Start(Seconds(0.0));
- producers.Stop(Seconds(20.0));
+ producers.Stop(finishTime);
NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
@@ -119,7 +121,7 @@
// NS_LOG_INFO ("FIB dump:\n" << *c.Get(0)->GetObject<CcnxFib> ());
// NS_LOG_INFO ("FIB dump:\n" << *c.Get(1)->GetObject<CcnxFib> ());
- Simulator::Stop (Seconds (100));
+ Simulator::Stop (finishTime);
NS_LOG_INFO ("Run Simulation.");
Simulator::Run ();
diff --git a/helper/ccnb-parser/ccnb-parser-common.h b/helper/ccnb-parser/ccnb-parser-common.h
index 847a6b8..528bcb0 100644
--- a/helper/ccnb-parser/ccnb-parser-common.h
+++ b/helper/ccnb-parser/ccnb-parser-common.h
@@ -168,8 +168,7 @@
CCN_DTAG_StatusResponse = 112,
CCN_DTAG_StatusCode = 113,
CCN_DTAG_StatusText = 114,
- NDN_DTAG_Nack = 115,
- NDN_DTAG_Congested = 116,
+ CCN_DTAG_Nack = 200,
CCN_DTAG_SequenceNumber = 256,
CCN_DTAG_CCNProtocolDataUnit = 17702112
};
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
index 65ec4ee..1964ac7 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
@@ -168,26 +168,15 @@
break;
- case NDN_DTAG_Nack:
+ case CCN_DTAG_Nack:
NS_LOG_DEBUG ("Nack");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
interest.SetNack (
- 1 == boost::any_cast<uint32_t> (
- (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
+ boost::any_cast<uint32_t> (
+ (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
break;
-
- case NDN_DTAG_Congested:
- NS_LOG_DEBUG ("Congested");
- if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
- throw CcnbDecodingException ();
-
- interest.SetCongested (
- 1 == boost::any_cast<uint32_t> (
- (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
- break;
- }
}
} // namespace CcnbParser
diff --git a/helper/ccnx-decoding-helper.cc b/helper/ccnx-decoding-helper.cc
index af945c5..408190b 100644
--- a/helper/ccnx-decoding-helper.cc
+++ b/helper/ccnx-decoding-helper.cc
@@ -43,9 +43,6 @@
Buffer::Iterator i = start;
Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
root->accept (interestVisitor, &interest);
-
- NS_LOG_DEBUG ("refs: " << root->GetReferenceCount ());
- NS_LOG_DEBUG ("refs: " << DynamicCast<CcnbParser::BaseTag> (root)->m_nestedTags.front ()->GetReferenceCount ());
return i.GetDistanceFrom (start);
}
diff --git a/helper/ccnx-encoding-helper.cc b/helper/ccnx-encoding-helper.cc
index 20ea101..f486c01 100644
--- a/helper/ccnx-encoding-helper.cc
+++ b/helper/ccnx-encoding-helper.cc
@@ -78,7 +78,7 @@
if (!interest.GetInterestLifetime().IsZero())
{
written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_InterestLifetime, CcnbParser::CCN_DTAG);
- written += AppendTimestampBlob (start, interest.GetInterestLifetime());
+ written += AppendTimestampBlob (start, interest.GetInterestLifetime ());
written += AppendCloser (start);
}
if (interest.GetNonce()>0)
@@ -89,16 +89,10 @@
sizeof(nonce));
}
- if (interest.IsNack ())
+ if (interest.GetNack ()>0)
{
- written += AppendBlockHeader (start, CcnbParser::NDN_DTAG_Nack, CcnbParser::CCN_DTAG);
- written += AppendNumber (start, 1);
- written += AppendCloser (start);
- }
- if (interest.IsCongested ())
- {
- written += AppendBlockHeader (start, CcnbParser::NDN_DTAG_Congested, CcnbParser::CCN_DTAG);
- written += AppendNumber (start, 1);
+ written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Nack, CcnbParser::CCN_DTAG);
+ written += AppendNumber (start, interest.GetNack ());
written += AppendCloser (start);
}
written += AppendCloser (start); // </Interest>
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index 110e7ac..9232ebc 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -150,7 +150,7 @@
}
-Ptr<Packet>
+boost::tuple<Ptr<Packet>, Ptr<CcnxContentObjectHeader> >
CcnxContentStore::Lookup (Ptr<const CcnxInterestHeader> interest)
{
NS_LOG_FUNCTION_NOARGS ();
@@ -162,9 +162,9 @@
m_contentStore.project<i_mru> (it));
// return fully formed CCNx packet
- return it->GetFullyFormedCcnxPacket ();
+ return boost::make_tuple (it->GetFullyFormedCcnxPacket (), it->GetHeader ());
}
- return 0;
+ return boost::tuple<Ptr<Packet>, Ptr<CcnxContentObjectHeader> > (0, 0);
}
void
diff --git a/model/ccnx-content-store.h b/model/ccnx-content-store.h
index 0bd8fb9..df92e1c 100644
--- a/model/ccnx-content-store.h
+++ b/model/ccnx-content-store.h
@@ -35,6 +35,7 @@
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
+#include <boost/tuple/tuple.hpp>
#include "ccnx.h"
#include "hash-helper.h"
@@ -173,7 +174,7 @@
* If an entry is found, it is promoted to the top of most recent
* used entries index, \see m_contentStore
*/
- Ptr<Packet>
+ boost::tuple<Ptr<Packet>, Ptr<CcnxContentObjectHeader> >
Lookup (Ptr<const CcnxInterestHeader> interest);
/**
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index 7821055..19eb21d 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -29,18 +29,6 @@
namespace ns3 {
-// NS_OBJECT_ENSURE_REGISTERED (CcnxFace);
-
-// TypeId
-// CcnxFace::GetTypeId (void)
-// {
-// static TypeId tid = TypeId ("ns3::CcnxFace")
-// .SetGroupName ("Ccnx")
-// .SetParent<Object> ()
-// ;
-// return tid;
-// }
-
/**
* By default, Ccnx face are created in the "down" state
* with no IP addresses. Before becoming useable, the user must
@@ -69,15 +57,6 @@
return *this;
}
-
-// void
-// CcnxFace::DoDispose (void)
-// {
-// NS_LOG_FUNCTION_NOARGS ();
-// m_node = 0;
-// Object::DoDispose ();
-// }
-
void
CcnxFace::SetNode (Ptr<Node> node)
{
@@ -132,15 +111,10 @@
}
bool
-CcnxFace::IsLocal() const
-{
- return m_isLocal;
-}
-
-bool
CcnxFace::operator== (const CcnxFace &face) const
{
- NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (), "Faces of different nodes should not be compared to each other");
+ NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
+ "Faces of different nodes should not be compared to each other");
return (m_id == face.m_id);
}
@@ -148,7 +122,8 @@
bool
CcnxFace::operator< (const CcnxFace &face) const
{
- NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (), "Faces of different nodes should not be compared to each other");
+ NS_ASSERT_MSG (m_node->GetId () == face.m_node->GetId (),
+ "Faces of different nodes should not be compared to each other");
return (m_id < face.m_id);
}
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index 481a55d..81700df 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -57,13 +57,6 @@
* \param packet Received packet
*/
typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
-
- // /**
- // * \brief Interface ID
- // *
- // * \return interface ID
- // */
- // static TypeId GetTypeId (void);
/**
* \brief Default constructor
@@ -135,11 +128,6 @@
* \brief Returns true if this face is disabled, false otherwise.
*/
virtual bool IsDown () const;
-
- /**
- * \brief Return true for LocalFace, otherwise false
- */
- virtual bool IsLocal () const;
virtual std::ostream&
Print (std::ostream &os) const;
@@ -179,9 +167,6 @@
*/
bool
operator< (const CcnxFace &face) const;
-
-// protected:
-// virtual void DoDispose (void);
private:
CcnxFace (const CcnxFace &); ///< \brief Disabled copy constructor
@@ -191,11 +176,10 @@
// uint16_t m_metric; ///< \brief Routing/forwarding metric
Ptr<Node> m_node; ///< \brief Smart pointer to Node
ProtocolHandler m_protocolHandler; ///< Callback via which packets are getting send to CCNx stack
- bool m_isLocal;
+
private:
bool m_ifup; ///< \brief flag indicating that the interface is UP
- uint32_t m_id; ///< \brief id of the interface in CCNx stack (per-node uniqueness)
-
+ uint32_t m_id; ///< \brief id of the interface in CCNx stack (per-node uniqueness)
};
std::ostream& operator<< (std::ostream& os, const CcnxFace &face);
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index 8daa034..9f23a83 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -36,6 +36,10 @@
//#define NDN_DEBUG_OSPF 0
//#define NDN_DEBUG_OSPF_NODES 0
+#include <boost/lambda/lambda.hpp>
+
+using namespace boost::lambda;
+
//#define NDN_DUMP_FIB 0
namespace ns3 {
@@ -51,48 +55,6 @@
type;
};
-struct ChangeStatus
-{
- ChangeStatus (CcnxFibFaceMetric::Status status) : m_status (status) { }
- void operator() (CcnxFibFaceMetric &entry)
- {
- entry.m_status = m_status;
- }
-private:
- CcnxFibFaceMetric::Status m_status;
-};
-
-struct ChangeMetric
-{
- ChangeMetric (int32_t metric) : m_metric (metric) { }
- void operator() (CcnxFibFaceMetric &entry)
- {
- entry.m_routingCost = m_metric;
- }
-private:
- int32_t m_metric;
-};
-
-// struct SearchByFace {
-// /**
-// * \brief To perform effective searches by CcnxFace
-// */
-// bool
-// operator() (const CcnxFibFaceMetric &m, const Ptr<CcnxFace> &face) const
-// {
-// return *(m.m_face) < *face;
-// }
-
-// /**
-// * \brief To perform effective searches by CcnxFace
-// */
-// bool
-// operator() (const Ptr<CcnxFace> &face, const CcnxFibFaceMetric &m) const
-// {
-// return *face < *(m.m_face);
-// }
-// };
-
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
@@ -112,69 +74,63 @@
return tid;
}
+/////////////////////////////////////////////////////////////////////
+
void
-CcnxFibFaceMetric::UpdateRtt::operator() (CcnxFibFaceMetric &entry)
+CcnxFibFaceMetric::UpdateRtt (const Time &rttSample)
{
// const Time & this->m_rttSample
//update srtt and rttvar (RFC 2988)
- if (entry.m_sRtt.IsZero ())
+ if (m_sRtt.IsZero ())
{
//first RTT measurement
- NS_ASSERT_MSG (entry.m_rttVar.IsZero (), "SRTT is zero, but variation is not");
+ NS_ASSERT_MSG (m_rttVar.IsZero (), "SRTT is zero, but variation is not");
- entry.m_sRtt = m_rttSample;
- entry.m_rttVar = Time (entry.m_sRtt / 2.0);
+ m_sRtt = rttSample;
+ m_rttVar = Time (m_sRtt / 2.0);
}
else
{
- entry.m_rttVar = Time ((1 - NDN_RTO_BETA) * entry.m_rttVar + NDN_RTO_BETA * Abs(entry.m_sRtt - m_rttSample));
- entry.m_sRtt = Time ((1 - NDN_RTO_ALPHA) * entry.m_sRtt + NDN_RTO_ALPHA * m_rttSample);
+ m_rttVar = Time ((1 - NDN_RTO_BETA) * m_rttVar + NDN_RTO_BETA * Abs(m_sRtt - rttSample));
+ m_sRtt = Time ((1 - NDN_RTO_ALPHA) * m_sRtt + NDN_RTO_ALPHA * rttSample);
}
}
+/////////////////////////////////////////////////////////////////////
+
void
-CcnxFibEntry::UpdateStatus::operator () (CcnxFibEntry &entry)
+CcnxFibEntry::UpdateStatus (const CcnxFace &face, CcnxFibFaceMetric::Status status)
{
- CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
- NS_ASSERT_MSG (record != entry.m_faces.get<i_face> ().end (),
+ CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
+ NS_ASSERT_MSG (record != m_faces.get<i_face> ().end (),
"Update status can be performed only on existing faces of CcxnFibEntry");
- entry.m_faces.modify (record, ChangeStatus (m_status));
+ m_faces.modify (record, _1->m_status = status);
// reordering random access index same way as by metric index
- entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
+ m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
}
-void
-CcnxFibEntry::AddOrUpdateRoutingMetric::operator () (CcnxFibEntry &entry)
-{
- NS_LOG_FUNCTION(this);
- NS_ASSERT_MSG (m_face != NULL, "Trying to Add or Update NULL face");
+// void
+// CcnxFibEntry::AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
+// {
+// NS_LOG_FUNCTION(this);
+// NS_ASSERT_MSG (m_face != NULL, "Trying to Add or Update NULL face");
- CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
- if (record == entry.m_faces.get<i_face> ().end ())
- {
- entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
- }
- else
- {
- entry.m_faces.modify (record, ChangeMetric (m_metric));
- }
- // reordering random access index same way as by metric index
- entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
-}
+// CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
+// if (record == entry.m_faces.get<i_face> ().end ())
+// {
+// entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
+// }
+// else
+// {
+// entry.m_faces.modify (record, ChangeMetric (m_metric));
+// }
+// // reordering random access index same way as by metric index
+// entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
+// }
-void
-CcnxFibEntry::UpdateFaceRtt::operator() (CcnxFibEntry &entry)
-{
- CcnxFibFaceMetricContainer::type::iterator metric = entry.m_faces.find (m_face);
- NS_ASSERT_MSG (metric != entry.m_faces.end (),
- "Something wrong. Cannot find entry for the face in FIB");
-
- entry.m_faces.modify (metric, CcnxFibFaceMetric::UpdateRtt (m_rttSample));
-}
-
Ptr<CcnxFace>
CcnxFibEntry::FindBestCandidate (int skip/* = 0*/) const
{
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index afb86a3..4410b59 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -81,16 +81,11 @@
GetFace () const { return m_face; }
/**
- * \brief Unary function to recalculate smoothed RTT and RTT variation
+ * \brief Recalculate smoothed RTT and RTT variation
* \param rttSample RTT sample
*/
- struct UpdateRtt
- {
- UpdateRtt (const Time &rttSample) : m_rttSample (rttSample) {};
- void operator() (CcnxFibFaceMetric &entry);
- private:
- const Time &m_rttSample;
- };
+ void
+ UpdateRtt (const Time &rttSample);
private:
friend std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric);
@@ -98,9 +93,9 @@
Ptr<CcnxFace> m_face; ///< Face
Status m_status; ///< \brief Status of the next hop:
- ///< - NDN_FIB_GREEN
- ///< - NDN_FIB_YELLOW
- ///< - NDN_FIB_RED
+ ///< - NDN_FIB_GREEN
+ ///< - NDN_FIB_YELLOW
+ ///< - NDN_FIB_RED
int32_t m_routingCost; ///< \brief routing protocol cost (interpretation of the value depends on the underlying routing protocol)
@@ -165,46 +160,17 @@
{ }
/**
- * \brief Unary function to update status of FIB next hop
+ * \brief Update status of FIB next hop
+ * \param status Status to set on the FIB entry
*/
- struct UpdateStatus
- {
- UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status)
- : m_face (face), m_status (status) {}
- void operator () (CcnxFibEntry &entry);
- private:
- Ptr<CcnxFace> m_face;
- CcnxFibFaceMetric::Status m_status;
- };
+ void UpdateStatus (const CcnxFace &face, CcnxFibFaceMetric::Status status);
- /**
- * \brief Unary function to add or update routing metric of FIB next hop
- *
- * Initial status of the next hop is set to YELLOW
- */
- struct AddOrUpdateRoutingMetric
- {
- AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
- : m_face (face), m_metric (metric) {}
- void operator () (CcnxFibEntry &entry);
- private:
- Ptr<CcnxFace> m_face;
- int32_t m_metric;
- };
-
- /**
- * \brief Unary function to recalculate smoothed RTT and RTT variation
- * \param rttSample RTT sample
- */
- struct UpdateFaceRtt
- {
- UpdateFaceRtt (Ptr<CcnxFace> face, const Time &rttSample)
- : m_face (face), m_rttSample (rttSample) {};
- void operator() (CcnxFibEntry &entry);
- private:
- Ptr<CcnxFace> m_face;
- const Time &m_rttSample;
- };
+ // /**
+ // * \brief Add or update routing metric of FIB next hop
+ // *
+ // * Initial status of the next hop is set to YELLOW
+ // */
+ // void AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric);
/**
* \brief Get prefix for the FIB entry
@@ -276,15 +242,6 @@
CcnxFib ();
// * \param node smart pointer to Ccnx stack associated with particular node
- // // Invalidate entries in FIB
- // // Will leave FIB records in hash, but assign metric=NETWORK_UNREACHABLE
- // void invalidate( );
-
- // //Find corresponding FIB entry for the given content name
- // //Longest match is performed
- // FibIterator lookup( const string &name );
- // bool isValid( const FibIterator &it ) { return it!=_fib.end(); }
-
/**
* \brief Perform longest prefix match
*
@@ -309,21 +266,6 @@
*/
CcnxFibEntryContainer::type::iterator
Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
- // bool update( const string &name, int interfaceIndex, int metric);
- // bool update( NodeAddress nodeId, int interfaceIndex, int metric);
- // Bool update( NodeAddress nodeId, int metric, NodeAddress nextHop );
-
- // // Update Fib from OSPF routing table (through a hack in OSPF algorithm)
- // void updateFibFromOSPFv2( int interface );
-
- // // Update Fib from BGP routing table (using info from RibIn)
- // void updateFibFromBGP( );
-
- // // Update Fib from IP routing table
- // void updateFibFromIpRouting( );
-
- // void dump( );
- // void dump( const FibIterator &fib );
// void resetProbing(); //reset needsProbing field for every FibEntry
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index f6295aa..cc21412 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.cc
@@ -56,8 +56,7 @@
, m_scope (-1)
, m_interestLifetime (Seconds (0))
, m_nonce (0)
- , m_nack (false)
- , m_congested (false)
+ , m_nackType (NORMAL_INTEREST)
{
}
@@ -178,28 +177,16 @@
}
void
-CcnxInterestHeader::SetNack (bool isNack)
+CcnxInterestHeader::SetNack (uint32_t nackType)
{
- m_nack = isNack;
+ m_nackType = nackType;
}
-
-bool
+
+uint32_t
CcnxInterestHeader::IsNack () const
{
return m_nack;
}
-
-void
-CcnxInterestHeader::SetCongested (bool IsCongested)
-{
- m_congested = IsCongested;
-}
-
-bool
-CcnxInterestHeader::IsCongested () const
-{
- return m_congested;
-}
uint32_t
CcnxInterestHeader::GetSerializedSize (void) const
@@ -232,10 +219,23 @@
CcnxInterestHeader::Print (std::ostream &os) const
{
os << "<Interest>\n <Name>" << GetName () << "</Name>\n";
- if (IsNack ())
- os << " <NACK />\n";
- if(IsCongested())
- os << " <CONGESTED />\n";
+ if (GetNack ()>0)
+ {
+ os << " <NACK>";
+ switch (GetNack ())
+ {
+ case NACK_LOOP:
+ os << "loop";
+ break;
+ case NACK_CONGESTION:
+ os << "congestion";
+ break;
+ default:
+ os << "unknown";
+ break;
+ }
+ os << "</NACK>\n";
+ }
if (GetMinSuffixComponents () >= 0)
os << " <MinSuffixComponents>" << GetMinSuffixComponents () << "</MinSuffixComponents>\n";
if (GetMaxSuffixComponents () >= 0)
diff --git a/model/ccnx-interest-header.h b/model/ccnx-interest-header.h
index 4bfebe3..d7be5fe 100644
--- a/model/ccnx-interest-header.h
+++ b/model/ccnx-interest-header.h
@@ -202,17 +202,18 @@
uint32_t
GetNonce () const;
+ enum
+ {
+ NORMAL_INTEREST = 0,
+ NACK_LOOP = 1,
+ NACK_CONGESTION,
+ };
+
void
- SetNack (bool isNack);
+ SetNack (uint32_t nackType);
- bool
- IsNack () const;
-
- void
- SetCongested (bool IsCongested);
-
- bool
- IsCongested () const;
+ uint32_t
+ GetNack () const;
//////////////////////////////////////////////////////////////////
@@ -233,8 +234,7 @@
int8_t m_scope; ///< -1 not set, 0 local scope, 1 this host, 2 immediate neighborhood
Time m_interestLifetime;
uint32_t m_nonce; ///< Nonce. not used if zero
- bool m_nack; ///< is Negative ACK
- bool m_congested; ///< NACK because of congestion
+ uint32_t m_nackType;
};
class CcnxInterestHeaderException {};
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 63c9049..a479390 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -41,6 +41,10 @@
#include "ccnx-net-device-face.h"
#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+
+using namespace boost::tuples;
+using namespace boost::lambda;
NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
@@ -257,8 +261,11 @@
// Deserialization. Exception may be thrown
packet->RemoveHeader (*header);
NS_ASSERT_MSG (packet->GetSize () == 0, "Payload of Interests should be zero");
-
- OnInterest (face, header, p/*original packet*/);
+
+ if (header->GetNack () > 0)
+ OnNack (face, header, p/*original packet*/);
+ else
+ OnInterest (face, header, p/*original packet*/);
break;
}
case CcnxHeaderHelper::CONTENT_OBJECT:
@@ -284,376 +291,199 @@
}
}
+void
+CcnxL3Protocol::OnNack (const Ptr<CcnxFace> &face,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &p)
+{
+ NS_LOG_FUNCTION (face << header << p);
+
+ // Huh... Ignore all this for now
+
+ /*if( header->IsCongested () == false )
+ m_pit->LeakBucket(incomingFace,1);
+
+
+ m_droppedInterestsTrace (header, DROP_CONGESTION,
+ m_node->GetObject<Ccnx> (), incomingFace);
+
+ m_pit->modify(pitEntry, CcnxPitEntry::DeleteOutgoing(incomingFace));*/
+
+ // No matter is it duplicate or not, if it is a NACK message, remove all possible incoming
+ // entries for this interface (NACK means that neighbor gave up trying and there is no
+ // point of sending data in this direction)
+
+ // NS_LOG_INFO("Before (header->IsNack()) && (pitEntry != m_pit->end ())");
+ // if ((header->IsNack()) && (pitEntry != m_pit->end ()))
+ // {
+ // //m_pit->erase (pitEntry);
+ // NS_LOG_INFO("TRUE");
+ // m_pit->modify(pitEntry, CcnxPitEntry::DeleteIncoming(incomingFace));
+ // }
+
+ // m_fib->modify (m_fib->iterator_to (pitEntry->m_fibEntry),
+ // CcnxFibEntry::UpdateStatus(incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+
+ // if (!pitEntry.AreThereMoreFacesToTry ())
+ // {
+ // BOOST_FOREACH (const CcnxPitEntryIncomingFace face, pitEntry.m_incoming)
+ // {
+ // // check all entries if the name of RIT entry matches the name of interest
+ // for (CcnxRitByNonce::type::iterator it = m_rit->begin(); it != m_rit->end(); it++)
+ // {
+ // if (it->m_prefix == iter->GetPrefix() )
+ // {
+ // header->SetNonce(it->m_nonce);
+ // header->SetNack(true);
+ // SendInterest(face.m_face, header, packet->Copy());
+ // }
+ // }
+ // }
+
+ // m_pit->erase(pitEntry);
+
+ // return;
+ // }
+}
+
// Processing Interests
+//
+// !!! Key point.
+// !!! All interests should be answerred!!! Either later with data, immediately with data, or immediately with NACK
void CcnxL3Protocol::OnInterest (const Ptr<CcnxFace> &incomingFace,
Ptr<CcnxInterestHeader> &header,
const Ptr<const Packet> &packet)
{
- NS_LOG_LOGIC ("Receiving interest from " << &incomingFace);
- m_receivedInterestsTrace (header, m_node->GetObject<Ccnx> (), incomingFace);
+ NS_LOG_FUNCTION (incomingFace << header << packet);
+ // m_receivedInterestsTrace (header, m_node->GetObject<Ccnx> (), incomingFace);
-
- if( header->IsNack () )
- {
- NS_LOG_INFO("============");
- NS_LOG_INFO("NACK");
- NS_LOG_INFO("==========");
- /*if( header->IsCongested () == false )
- m_pit->LeakBucket(incomingFace,1);
-
-
- m_droppedInterestsTrace (header, DROP_CONGESTION,
- m_node->GetObject<Ccnx> (), incomingFace);
-
- m_pit->modify(pitEntry, CcnxPitEntry::DeleteOutgoing(incomingFace));*/
- }
+ // Lookup of Pit (and associated Fib) entry for this Interest
+ const CcnxPitEntry &pitEntry;
+ bool isNew;
+ bool isDuplicated;
+ tie (pitEntry, isNew, isDuplicated) = m_pit->Lookup (*header);
-
-
-
- // Lookup of Pit and Fib entries for this Interest
- CcnxFibEntryContainer::type::iterator fibEntry;
- CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header, fibEntry);
-
- // No matter is it duplicate or not, if it is a NACK message, remove all possible incoming
- // entries for this interface (NACK means that neighbor gave up trying and there is no
- // point of sending data in this direction)
- NS_LOG_INFO("Before (header->IsNack()) && (pitEntry != m_pit->end ())");
- if ((header->IsNack()) && (pitEntry != m_pit->end ()))
+ if (isDuplicated)
{
- //m_pit->erase (pitEntry);
- NS_LOG_INFO("TRUE");
- m_pit->modify(pitEntry, CcnxPitEntry::DeleteIncoming(incomingFace));
- }
-
- NS_LOG_INFO("Before WasRecentlySatisfied");
- /*if (m_rit->WasRecentlySatisfied (*header))
- {
- return;
- }*/
- if (m_rit->WasRecentlySatisfied (*header))
- {
- NS_LOG_INFO("------------");
- NS_LOG_INFO("Entering WasRecentlySatisfied");
- NS_LOG_INFO("------------");
- // duplicate interests (same nonce) from applications are just ignored
- if (incomingFace->IsLocal() == true)
- return;
-
- // Update metric status for the incoming interface in the corresponding FIB entry
- /*if (fibEntry != m_fib->end())
- m_fib->modify (m_fib->iterator_to (pitEntry->m_fibEntry),
- CcnxFibEntry::UpdateStatus(incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+ /**
+ * This condition will handle "routing" loops and also recently satisfied interests.
+ * Every time interest is satisfied, PIT entry (with empty incoming and outgoing faces)
+ * is kept for another small chunk of time.
+ */
- //Trace duplicate interest
- m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
-
- bool isMine = false;
- //TypeId tid = TypeId ("ns3::CcnxProducer");
- for(uint32_t i=0; i<m_node->GetNApplications();i++)
- {
- Ptr<Application> app = m_node->GetApplication(i);
- NS_LOG_INFO("ApplicationName = " << app->GetTypeId().GetName());
- if(app->GetTypeId().GetName() == "ns3::CcnxProducer")
- {
- if((DynamicCast<CcnxProducer>(app))->GetPrefix () == header->GetName ())
- {
- isMine = true;
- break;
- }
- }
- }
-
- Ptr<Packet> contentObject = m_contentStore->Lookup (header);
- if ((isMine == true) || (contentObject != NULL))
- {
- //never respond with NACK to NACK
- if(header->IsNack () )
- return;
-
- // always return a duplicate packet
- header->SetNack(true);
- //Trace duplicate interest
- m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
+ // //Trace duplicate interest
+ // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
- SendInterest(incomingFace, header, packet->Copy());
-
- return;
- }
-
-
- // check PIT. or there is no outgoing entry for this interface,
- // silently drop the duplicate packet
-
- // If no entry found, silently drop
- if( pitEntry == m_pit->end() )
- return;
-
- // If PIT entry timed out, silently drop
- if( pitEntry->m_timerExpired == true )
- return;
-
- // loop?
-
- // Check if there is no outgoing entry for the interface or different nonce
- // (i.e., got a duplicate packet, but we haven't sent interest to this
- // interface)
- //
- // This case means that there is a loop in the network.
- // So, prune this link, but do not remove PIT entry
-
- // Alex, check this condition!!
- if(pitEntry->m_outgoing.size () == 0)
- {
- //never respond with NACK to NACK
- if(header->IsNack () )
- return;
-
- // always return a duplicate packet
- header->SetNack(true);
- //Trace duplicate interest
- m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
+ header->SetNack (CcnxInterestHeader::NACK_LOOP);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (*header);
- SendInterest(incomingFace, header, packet->Copy());
- return;
- }
+ SendInterest (m_incomingFace, header, packet);
-
- // At this point:
- // - there is a non-expired PIT entry,
- // - there is an outgoing interest to the interface, and
- // - a nonce in outgoing entry is equal to a nonce in the received duplicate packet
-
- // Should perform:
- // Cleaning outgoing entry
- // If there are no outgoing interests and available interfaces left (pe->availableInterfaces),
- // prune all incoming interests, otherwise allow forwarding of the interest
- if( header->IsNack () )
- {
- if( header->IsCongested () == false )
- m_pit->LeakBucket(incomingFace,1);
-
- m_pit->modify(pitEntry, CcnxPitEntry::DeleteOutgoing(incomingFace));
- }
- else
- {
- //poit->waitingInVain = true;
- }
-
-
- // prune all incoming interests
- if((pitEntry->m_outgoing.size() ==0) && (pitEntry->m_fibEntry.m_faces.size() == 0))
- {
- BOOST_FOREACH (const CcnxPitEntryIncomingFace face, pitEntry->m_incoming)
- {
- if(face.m_face->IsLocal() == false)
- {
- // check all entries if the name of RIT entry matches the name of interest
- for (CcnxRitByNonce::type::iterator it = m_rit->begin(); it != m_rit->end(); it++)
- {
- if (it->m_prefix == pitEntry->GetPrefix() )
- {
-
- header->SetNonce(it->m_nonce);
- header->SetNack(true);
- SendInterest(face.m_face, header, packet->Copy());
- break;
- }
- }
- }
- }
-
- // Finally, remote the PIT entry
- m_pit->erase (pitEntry);
-
- return; // stop processing
- }
-
- if(pitEntry->m_fibEntry.m_faces.size() == 0)
- return;*/
- return;
- }
-
-
-
- // Otherwise,
- // propagate the interest
- //
- // method `propagateInterest' can/should try different interface
- // from `availableInterfaces' list
-
- NS_LOG_INFO("Before SetRecentlySatisfied");
- m_rit->SetRecentlySatisfied (*header);
-
- NS_LOG_INFO("Cache Lookup for " << header->GetName());
- Ptr<Packet> contentObject = m_contentStore->Lookup (header);
- if (contentObject != NULL)
- {
- NS_LOG_INFO("Found in cache");
-
- TransmittedDataTrace (contentObject, CACHED,
- m_node->GetObject<Ccnx> (), incomingFace);
- incomingFace->Send (contentObject);
+ // //Trace duplicate interest
+ // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
return;
}
+
+ Ptr<Packet> contentObject;
+ Ptr<CcnxContentObjectHeader> contentObjectHeader;
+ tie (contentObject, contentObjectHeader) = m_contentStore->Lookup (header);
+ if (contentObject != 0)
+ {
+ NS_ASSERT_MSG (pitEntry.m_incoming.size () == 0,
+ "Something strange. Data is cached, but size of incoming interests is not zero...");
+ NS_ASSERT (contentObjectHeader != 0);
+
+ NS_LOG_LOGIC("Found in cache");
+
+ // TransmittedDataTrace (contentObject, CACHED,
+ // m_node->GetObject<Ccnx> (), incomingFace);
+ SendContentObject (incomingFace, contentObjectHeader, contentObject);
+
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ boost::bind (&CcnxPitEntry::SetExpireTime, _1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ return;
+ }
+
+ // \todo Detect retransmissions. Not yet sure how...
// Data is not in cache
- NS_LOG_INFO("Before inFace and OutFace");
- CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry->m_incoming.find (incomingFace);
- CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry->m_outgoing.find (incomingFace);
-
- NS_LOG_INFO("Before (pitEntry != m_pit->end()) && (pitEntry->m_timerExpired == false)");
- if ((pitEntry != m_pit->end()) && (pitEntry->m_timerExpired == false))
+ CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
+
+ if (inFace != pitEntry.m_incoming.end ())
{
- NS_LOG_INFO("Entering (pitEntry != m_pit->end()) && (pitEntry->m_timerExpired == false)");
-
- if(inFace->m_face == 0)
- NS_LOG_INFO("in face is null");
- if(outFace->m_face == 0)
- NS_LOG_INFO("outface is null");
- if(outFace == pitEntry->m_outgoing.end())
- NS_LOG_INFO("OUTFACE = END");
-
- // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
- // Give up this interface, but keep a small hope when the returned packet doesn't have PRUNE status
- if(outFace != pitEntry->m_outgoing.end()) // this is correct
- {
- NS_LOG_INFO("Entering outFace != pitEntry->m_outgoing.end()");
- if( header->IsCongested() == true )
- {
- NS_LOG_INFO("Entering header->IsCongested() == true");
- m_pit->LeakBucket(incomingFace, 1);
- m_pit->modify (pitEntry, CcnxPitEntry::DeleteOutgoing(outFace->m_face));
- }
- //else
- // poit->waitingInVain = true;
-
- // Update metric status for the incoming interface in the corresponding FIB entry
- if(fibEntry != m_fib->end())
- m_fib->modify(m_fib->iterator_to (pitEntry->m_fibEntry),
- CcnxFibEntry::UpdateStatus(incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
- }
- }
-
- NS_LOG_INFO("Before (pitEntry->m_outgoing.size() == 0) && (pitEntry->m_fibEntry.m_faces.size() == 0)");
- if((pitEntry->m_outgoing.size() == 0) && (pitEntry->m_fibEntry.m_faces.size() == 0))
- // prune all incoming interests
- {
-
- for(CcnxPitEntryContainer::type::iterator iter = m_pit->begin();
- iter != m_pit->end();
- iter++)
- {
- /*for(CcnxPitEntryIncomingFaceContainer::type::iterator face = iter->m_incoming.begin();
- face != iter->m_incoming.end();
- face++)*/
- BOOST_FOREACH (const CcnxPitEntryIncomingFace face, iter->m_incoming)
- {
- if(face.m_face->IsLocal() == true)
- {
- //returnInterestToApp( pkt, -piit->interfaceIndex );
- //continue;
- }
-
- // check all entries if the name of RIT entry matches the name of interest
- for (CcnxRitByNonce::type::iterator it = m_rit->begin(); it != m_rit->end(); it++)
- {
- if (it->m_prefix == iter->GetPrefix() )
- {
- header->SetNonce(it->m_nonce);
- header->SetNack(true);
- SendInterest(face.m_face, header, packet->Copy());
- }
- }
- }
-
- }
-
- m_pit->erase(pitEntry);
-
- return; // there is nothing else to do
- }
-
- // Suppress this interest only if we're still expecting data from some other interface
- if( pitEntry->m_outgoing.size() > 0 )
- {
- return; //ok. Now we can suppress this interest
- }
-
-
- // Prune and delete PIT entry if there are no available interfaces to propagate interest
- if( pitEntry->m_fibEntry.m_faces.size() == 0)
- {
- //if no match is found in the FIB, drop packet
- //printf( "Node %d: cannot process Interest packet %s (no interfaces left)\n", _node->nodeId, pkt->contentName );
-
- if(incomingFace->IsLocal() == false)
- {
- header->SetNack(true);
- m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
- SendInterest(incomingFace, header, packet->Copy());
- }
-
- m_pit->erase(pitEntry);
-
- }
-
-
-
- // otherwise, try one of the available interfaces
-
- // suppress interest if
- /*if (pitEntry->m_incoming.size () != 0 && // not a new PIT entry and
- inFace != pitEntry->m_incoming.end ()) // existing entry, but interest received via different face
- {
- m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
- return;
- }*/
-
-
- //just in case of bug
- header->SetNack(false);
- header->SetCongested(false);
-
- NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
-
- m_pit->modify (pitEntry, CcnxPitEntry::AddIncoming(incomingFace));
-
- bool propagated = m_forwardingStrategy->
- PropagateInterest (pitEntry, fibEntry,incomingFace, header, packet,
- MakeCallback (&CcnxL3Protocol::SendInterest, this)
- );
-
- // If interest wasn't propagated further (probably, a limit is reached),
- // prune and delete PIT entry if there are no outstanding interests.
- // Stop processing otherwise.
- if( (!propagated) && (pitEntry->m_outgoing.size() == 0)) // this line works
- {
- BOOST_FOREACH (const CcnxPitEntryIncomingFace face, pitEntry->m_incoming)
- {
- header->SetNack(true);
- header->SetCongested(true);
- NS_LOG_INFO("Sending CONGESTION packet");
- SendInterest (face.m_face, header, packet->Copy());
-
- m_droppedInterestsTrace (header, DROP_CONGESTION,
- m_node->GetObject<Ccnx> (), incomingFace);
- }
+ // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
- m_pit->erase (pitEntry);
- }
- /*}
+ // this is almost definitely a retransmission. But should we trust the user on that?
+ }
else
{
- m_droppedInterestsTrace (header, NDN_PIT_TIMER_EXPIRED,
- m_node->GetObject<Ccnx> (), incomingFace);
- return;
- }*/
+ m_pit->modify (m_pit->iterator_to (m_pitpitEntry),
+ iface = _1->m_incoming.insert (CcnxPitEntryIncoming (incomingFace, Simulator::Now ())));
+ }
+
+ if (outFace != pitEntry.m_outgoing.end ())
+ {
+ // got a non-duplicate interest from the face we have sent interest to
+ // Probably, there is no point in waiting data from that face... Not sure yet
+
+ // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
+ // Mark interface YELLOW, but keep a small hope that data will come eventually.
+
+ // ?? not sure if we need to do that ?? ...
+
+ m_fib->modify(m_fib->iterator_to (pitEntry.m_fibEntry),
+ boost::bind (&CcnxFibEntry::UpdateStatus,
+ _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+
+ // suppress?
+ }
+ else if (pitEntry->m_outgoing.size() > 0) // Suppress this interest if we're still expecting data from some other face
+
+ {
+ // We are already expecting data later in future. Suppress the interest
+ // m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
+ return;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ // Propagate
+ /////////////////////////////////////////////////////////////////////
+
+ NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
+
+ bool propagated = m_forwardingStrategy->
+ PropagateInterest (pitEntry, fibEntry,incomingFace, header, packet,
+ MakeCallback (&CcnxL3Protocol::SendInterest, this)
+ );
+
+ // ForwardingStrategy will try its best to forward packet to at least one interface.
+ // If no interests was propagated, then there is not other option for forwarding or
+ // ForwardingStrategy failed to find it.
+ if (!propagated)
+ {
+ Ptr<Packet> packet = Create<Packet> ();
+ header->SetNack (CcnxInterestHeader::NACK_CONGESTION);
+ packet.AddHeader (*header);
+
+ while (pitEntry.m_incoming.size () > 0)
+ {
+ SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
+
+ pitEntry.m_incoming.pop_front ();
+
+ // m_droppedInterestsTrace (header, DROP_CONGESTION,
+ // m_node->GetObject<Ccnx> (), incomingFace);
+ }
+
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ boost::bind (&CcnxPitEntry::SetExpireTime, _1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ }
}
// Processing ContentObjects
@@ -663,8 +493,8 @@
const Ptr<const Packet> &packet)
{
- NS_LOG_LOGIC ("Receiving contentObject from " << &incomingFace);
- m_receivedDataTrace (header, payload, m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
+ NS_LOG_FUNCTION (incomingFace << header, payload, packet);
+ // m_receivedDataTrace (header, payload, m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
// 1. Lookup PIT entry
try
@@ -675,46 +505,48 @@
// Update metric status for the incoming interface in the corresponding FIB entry
m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
- CcnxFibEntry::UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
+ boost::bind (CcnxFibEntry::UpdateStatus, _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
// Add or update entry in the content store
- NS_LOG_INFO("Cached " << header->GetName());
m_contentStore->Add (header, payload);
- 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 ())
{
- m_pit->modify (m_pit->iterator_to (pitEntry),
- CcnxPitEntry::EstimateRttAndRemoveFace(out, m_fib));
- // face will be removed in the above call
+ m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
+ boost::bind (&CcnxFibEntry::UpdateRtt,
+ _1,
+ Simulator::Now () - out->m_sendTime));
}
else
{
- NS_LOG_WARN ("Node "<< m_node->GetId() <<
- ". PIT entry for "<< header->GetName ()<<" is valid, "
- "but outgoing entry for interface "<< incomingFace <<" doesn't exist\n");
+ // Unsolicited data, but we're interested in it... should we get it?
+ // Potential hole for attacks
+
+ NS_LOG_ERROR ("Node "<< m_node->GetId() <<
+ ". PIT entry for "<< header->GetName ()<<" is valid, "
+ "but outgoing entry for interface "<< incomingFace <<" doesn't exist\n");
+
+ NS_ASSERT (false); // temporary put false here
}
//satisfy all pending incoming Interests
- BOOST_FOREACH (const CcnxPitEntryIncomingFace &interest, pitEntry.m_incoming)
+ while (pitEntry.m_incoming.size () > 0)
{
- if (interest.m_face == incomingFace) continue;
+ if (pitEntry.m_incoming.front ().m_face != incomingFace)
+ SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
- // may not work either because of 'const' thing
- interest.m_face->Send (packet->Copy ()); // unfortunately, we have to copy packet...
- m_transmittedDataTrace (header, payload, FORWARDED, m_node->GetObject<Ccnx> (), interest.m_face);
+ pitEntry.m_incoming.pop_front ();
+
+ // m_transmittedDataTrace (header, payload, FORWARDED, m_node->GetObject<Ccnx> (), interest.m_face);
}
- m_pit->modify (m_pit->iterator_to (pitEntry), CcnxPitEntry::ClearIncoming()); // satisfy all incoming interests
-
- if( pitEntry.m_outgoing.size()==0 ) // remove PIT when all outgoing interests are "satisfied"
- {
- m_pit->erase (m_pit->iterator_to (pitEntry));
- }
-
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ boost::bind (&CcnxPitEntry::SetExpireTime, _1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
}
catch (CcnxPitEntryNotFound)
{
@@ -722,7 +554,7 @@
// (unsolicited data packets should not "poison" content store)
//drop dulicated or not requested data packet
- m_droppedDataTrace (header, payload, NDN_UNSOLICITED_DATA, m_node->GetObject<Ccnx> (), incomingFace);
+ // m_droppedDataTrace (header, payload, NDN_UNSOLICITED_DATA, m_node->GetObject<Ccnx> (), incomingFace);
return; // do not process unsoliced data packets
}
}
@@ -738,13 +570,13 @@
if (face->IsUp ())
{
NS_LOG_LOGIC ("Sending via face " << &face); //
- m_transmittedInterestsTrace (header, m_node->GetObject<Ccnx> (), face);
+ // m_transmittedInterestsTrace (header, m_node->GetObject<Ccnx> (), face);
face->Send (packet);
}
else
{
NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
- m_droppedInterestsTrace (header, INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
+ // m_droppedInterestsTrace (header, INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
}
}
@@ -756,8 +588,6 @@
NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face);
NS_ASSERT_MSG (face != 0, "Face should never be NULL");
- NS_ASSERT_MSG (false, "Should not be called for now");
-
if (face->IsUp ())
{
NS_LOG_LOGIC ("Sending via face " << &face); //
@@ -777,11 +607,12 @@
return m_pit;
}
-void
-CcnxL3Protocol::ScheduleLeakage()
-{
- m_pit->LeakBuckets();
- Time interval = MilliSeconds (NDN_INTEREST_RESET_PERIOD);
- Simulator::Schedule (interval, &CcnxL3Protocol::ScheduleLeakage, this);
-}
+// void
+// CcnxL3Protocol::ScheduleLeakage()
+// {
+// m_pit->LeakBuckets();
+// Time interval = MilliSeconds (NDN_INTEREST_RESET_PERIOD);
+
+// Simulator::Schedule (interval, &CcnxL3Protocol::ScheduleLeakage, this);
+// }
} //namespace ns3
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 3e2c870..3605da4 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -152,7 +152,7 @@
Ptr<CcnxPit> GetPit();
- void ScheduleLeakage();
+ // void ScheduleLeakage();
protected:
/**
* \brief Actual processing of incoming CCNx interests. Note, interests do not have payload
@@ -167,6 +167,18 @@
Ptr<CcnxInterestHeader> &header,
const Ptr<const Packet> &p);
+ /**
+ * \brief Processing of incoming CCNx NACKs. Note, these packets, like interests, do not have payload
+ *
+ * Processing NACK packets
+ * @param face incoming face
+ * @param header deserialized Interest header
+ * @param packet original packet
+ */
+ virtual void
+ OnNack (const Ptr<CcnxFace> &face,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &p);
/**
* \brief Actual processing of incoming CCNx content objects
@@ -196,12 +208,6 @@
CcnxL3Protocol(const CcnxL3Protocol &); ///< copy constructor is disabled
CcnxL3Protocol &operator = (const CcnxL3Protocol &); ///< copy operator is disabled
- // /**
- // * \brief Fake function. should never be called. Just to trick C++ to compile
- // */
- // virtual void
- // ReceiveAndProcess (const Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p);
-
/**
* \brief A helper function
*/
@@ -218,7 +224,7 @@
Ptr<Node> m_node; ///< \brief node on which ccnx stack is installed
Ptr<CcnxForwardingStrategy> m_forwardingStrategy; ///< \brief smart pointer to the selected forwarding strategy
- Ptr<CcnxRit> m_rit; ///< \brief RIT (recently interest table)
+ // Ptr<CcnxRit> m_rit; ///< \brief RIT (recently interest table)
Ptr<CcnxPit> m_pit; ///< \brief PIT (pending interest table)
Ptr<CcnxFib> m_fib; ///< \brief FIB
Ptr<CcnxContentStore> m_contentStore; ///< \brief Content store (for caching purposes only)
diff --git a/model/ccnx-pit-entry-incoming-face.h b/model/ccnx-pit-entry-incoming-face.h
index 80f7e09..9a3859f 100644
--- a/model/ccnx-pit-entry-incoming-face.h
+++ b/model/ccnx-pit-entry-incoming-face.h
@@ -44,7 +44,7 @@
* \param face face of the incoming interest
* \param lifetime lifetime of the incoming interest
*/
- CcnxPitEntryIncomingFace (Ptr<CcnxFace> face);
+ CcnxPitEntryIncomingFace (Ptr<CcnxFace> face, Time arrivalTime);
bool operator== (const CcnxPitEntryIncomingFace &dst) { return *m_face==*(dst.m_face); }
bool operator== (Ptr<CcnxFace> face) { return *m_face==*face; }
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index ddc471e..5dab9ae 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -27,50 +27,12 @@
namespace ns3
{
-// struct SearchByFace
-// {
-// /**
-// * \brief To perform effective searches by CcnxFace
-// */
-// bool
-// operator() (const CcnxPitIncomingInterest &m, const Ptr<CcnxFace> &face) const
-// {
-// return *(m.m_face) < *face;
-// }
-
-// /**
-// * \brief To perform effective searches by CcnxFace
-// */
-// bool
-// operator() (const Ptr<CcnxFace> &face, const CcnxPitIncomingInterest &m) const
-// {
-// return *face < *(m.m_face);
-// }
-
-// /**
-// * \brief To perform effective searches by CcnxFace
-// */
-// bool
-// operator() (const CcnxPitOutgoingInterest &m, const Ptr<CcnxFace> &face) const
-// {
-// return *(m.m_face) < *face;
-// }
-
-// /**
-// * \brief To perform effective searches by CcnxFace
-// */
-// bool
-// operator() (const Ptr<CcnxFace> &face, const CcnxPitOutgoingInterest &m) const
-// {
-// return *face < *(m.m_face);
-// }
-// };
-
-
-CcnxPitEntry::CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const CcnxFibEntry &fibEntry)
+CcnxPitEntry::CcnxPitEntry (Ptr<CcnxNameComponents> prefix,
+ const Time &expireTime,
+ const CcnxFibEntry &fibEntry)
: m_prefix (prefix)
, m_fibEntry (fibEntry)
- // , m_expireTime (?)
+ , m_expireTime (expireTime)
, m_timerExpired (false)
, m_counterExpirations (0)
{
@@ -82,76 +44,42 @@
return *m_prefix;
}
-// CcnxPitEntry::SetFibEntry::SetFibEntry (Ptr<CcnxFibEntry> fib)
-// : m_fib (fib)
+// void
+// CcnxPitEntry::AddIncoming (Ptr<CcnxFace> face)
+// {
+// m_incoming.insert (CcnxPitEntryIncomingFace (face, )
+// }
+
+
+// CcnxPitEntry::UpdateFibStatus::UpdateFibStatus (Ptr<CcnxFace> face,
+// CcnxFibFaceMetric::Status status,
+// Ptr<CcnxFib> fib)
+// : m_face (face)
+// , m_status (status)
+// , m_fib (fib)
// {
// }
// void
-// CcnxPitEntry::SetFibEntry::operator() (CcnxPitEntry &entry)
+// CcnxPitEntry::UpdateFibStatus::operator() (CcnxPitEntry &entry)
// {
-// entry.m_fib = m_fib;
+// NS_ASSERT_MSG (false, "Broken");
+// m_fib->modify (m_fib->iterator_to (entry.m_fibEntry),
+// CcnxFibEntry::UpdateStatus (m_face, m_status));
// }
-void
-CcnxPitEntry::AddIncoming::operator() (CcnxPitEntry &entry)
-{
- entry.m_incoming.insert (CcnxPitEntryIncomingFace (m_face));
-}
+// void
+// CcnxPitEntry::EstimateRttAndRemoveFace::operator() (CcnxPitEntry &entry)
+// {
+// // similar to Karn's Algorithm, we don't use RTT measurements for retx packets
+// if (m_outFace->m_retxNum>0)
+// return;
-void
-CcnxPitEntry::DeleteIncoming::operator() (CcnxPitEntry &entry)
-{
- entry.m_incoming.erase (m_face);
-}
+// m_fib->modify (m_fib->iterator_to (entry.m_fibEntry),
+// CcnxFibEntry::UpdateFaceRtt (m_outFace->m_face,
+// Simulator::Now() - m_outFace->m_sendTime));
-void
-CcnxPitEntry::AddOutgoing::operator() (CcnxPitEntry &entry)
-{
- entry.m_outgoing.insert (CcnxPitEntryOutgoingFace (m_face));
-}
-
-void
-CcnxPitEntry::DeleteOutgoing::operator() (CcnxPitEntry &entry)
-{
- entry.m_outgoing.erase (m_face);
-}
-
-void
-CcnxPitEntry::ClearIncoming::operator() (CcnxPitEntry &entry)
-{
- entry.m_incoming.clear ();
-}
-
-CcnxPitEntry::UpdateFibStatus::UpdateFibStatus (Ptr<CcnxFace> face,
- CcnxFibFaceMetric::Status status,
- Ptr<CcnxFib> fib)
- : m_face (face)
- , m_status (status)
- , m_fib (fib)
-{
-}
-
-void
-CcnxPitEntry::UpdateFibStatus::operator() (CcnxPitEntry &entry)
-{
- NS_ASSERT_MSG (false, "Broken");
- m_fib->modify (m_fib->iterator_to (entry.m_fibEntry),
- CcnxFibEntry::UpdateStatus (m_face, m_status));
-}
-
-void
-CcnxPitEntry::EstimateRttAndRemoveFace::operator() (CcnxPitEntry &entry)
-{
- // similar to Karn's Algorithm, we don't use RTT measurements for retx packets
- if (m_outFace->m_retxNum>0)
- return;
-
- m_fib->modify (m_fib->iterator_to (entry.m_fibEntry),
- CcnxFibEntry::UpdateFaceRtt (m_outFace->m_face,
- Simulator::Now() - m_outFace->m_sendTime));
-
- entry.m_outgoing.erase (m_outFace);
-}
+// entry.m_outgoing.erase (m_outFace);
+// }
}
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index fa89b5e..59f2a3e 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -34,6 +34,7 @@
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
+#include <set>
#include <iostream>
@@ -102,127 +103,42 @@
* \param prefix Prefix of the PIT entry
* \param fibEntry A FIB entry associated with the PIT entry
*/
- CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const CcnxFibEntry &fibEntry);
+ CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const Time &expireTime, const CcnxFibEntry &fibEntry);
// // Get number of outgoing interests that we're expecting data from
// inline size_t numberOfPromisingInterests( ) const;
- // /**
- // * \brief Unary function to set or update FIB entry with this PIT entry
- // * \param fib smart pointer to FIB entry
- // */
- // struct SetFibEntry
- // {
- // SetFibEntry (Ptr<CcnxFibEntry> fib);
- // void operator() (CcnxPitEntry &entry);
- // private:
- // Ptr<CcnxFibEntry> m_fib;
- // };
-
- /**
- * \brief Unary Function to add incoming interest to the PIT entry
- *
- * \param incomingFace smart pointer to the face of the incoming interest
- * \returns const iterator to a newly added or updated
- * CcnxPitIncomingInterest entry
- */
- struct AddIncoming
- {
- AddIncoming (Ptr<CcnxFace> incomingFace) : m_face (incomingFace) {}
- void operator() (CcnxPitEntry &entry);
-
- private:
- Ptr<CcnxFace> m_face;
- Time m_lifeTime;
- };
-
- /**
- * \brief Unary function to delete incoming interest for the interface
- * \param face face that should be removed from the list of incoming interests
- */
- struct DeleteIncoming
- {
- DeleteIncoming (Ptr<CcnxFace> face) : m_face (face) {}
- void operator() (CcnxPitEntry &entry);
- private:
- Ptr<CcnxFace> m_face;
- };
-
- /**
- * \brief Unary function to add outgoing interest to PIT entry
- *
- * \param outgoingFace smart pointer to the face of the outgoing interest
- * \returns const iterator to a newly added or updated
- * CcnxPitOutgoingInterest entry
- */
- struct AddOutgoing
- {
- AddOutgoing (Ptr<CcnxFace> outgoingFace) : m_face (outgoingFace) {}
- void operator() (CcnxPitEntry &entry);
- private:
- Ptr<CcnxFace> m_face;
- };
-
- /**
- * \brief Unary function to delete incoming interest for the interface
- * \param face face that should be removed from the list of incoming interests
- */
- struct DeleteOutgoing
- {
- DeleteOutgoing (Ptr<CcnxFace> face) : m_face (face) {}
- void operator() (CcnxPitEntry &entry);
- private:
- Ptr<CcnxFace> m_face;
- };
-
- /**
- * \brief Unary function to remove all incoming interests
- */
- struct ClearIncoming
- {
- ClearIncoming () {};
- void operator() (CcnxPitEntry &entry);
- };
-
- /**
- * \brief Unary function to update FIB status
- */
- struct UpdateFibStatus
- {
- UpdateFibStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status, Ptr<CcnxFib> fib);
- void operator() (CcnxPitEntry &entry);
- private:
- Ptr<CcnxFace> m_face;
- CcnxFibFaceMetric::Status m_status;
- Ptr<CcnxFib> m_fib;
- };
-
- /**
- * \brief Unary function to estimate RTT and update smoothed RTT value in FIB
- * \param outFace iterator of the outgoing face entry
- */
- struct EstimateRttAndRemoveFace
- {
- EstimateRttAndRemoveFace (CcnxPitEntryOutgoingFaceContainer::type::iterator outFace, Ptr<CcnxFib> fib)
- : m_outFace (outFace), m_fib (fib) { };
- void operator() (CcnxPitEntry &entry);
- private:
- CcnxPitEntryOutgoingFaceContainer::type::iterator m_outFace;
- Ptr<CcnxFib> m_fib;
- };
-
const CcnxNameComponents &
GetPrefix () const;
const Time &
- GetExpireTime () const { return m_expireTime; }
+ GetExpireTime () const
+ { return m_expireTime; }
+ void
+ SetExpireTime (const Time &expireTime)
+ {
+ m_expireTime = expireTime;
+ }
+
+ bool
+ IsNonceSeen (uint32_t nonce) const
+ { return m_seenNonces.find (nonce) != m_seenNonces.end (); }
+
+ void
+ AddSeenNonce (uint32_t nonce)
+ { m_seenNonces.insert (nonce); }
+
+ void
+ AddIncoming (const CcnxFace &face);
+
private:
friend std::ostream& operator<< (std::ostream& os, const CcnxPitEntry &entry);
public:
Ptr<CcnxNameComponents> m_prefix; ///< \brief Prefix of the PIT entry
const CcnxFibEntry &m_fibEntry; ///< \brief FIB entry related to this prefix
+ std::set<uint32_t> m_seenNonces; ///< \brief map of nonces that were seen for this prefix
CcnxPitEntryIncomingFaceContainer::type m_incoming; ///< \brief container for incoming interests
CcnxPitEntryOutgoingFaceContainer::type m_outgoing; ///< \brief container for outgoing interests
@@ -232,7 +148,6 @@
int m_counterExpirations; ///< \brief whether timer is expired (+ number of times timer expired)
};
-
} // namespace ns3
#endif // _CCNX_PIT_ENTRY_H_
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index f51aa33..3017857 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -26,13 +26,15 @@
NS_LOG_COMPONENT_DEFINE ("CcnxPit");
+using namespace boost::tuples;
+
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (CcnxPit);
using namespace __ccnx_private;
-TypeId
+TypeId
CcnxPit::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::CcnxPit")
@@ -44,6 +46,11 @@
TimeValue (Seconds (1)),
MakeTimeAccessor (&CcnxPit::GetCleanupTimeout, &CcnxPit::SetCleanupTimeout),
MakeTimeChecker ())
+ .AddAttribute ("PitEntryPruningTimout",
+ "Timeout for PIT entry to live after being satisfied. To make sure recently satisfied interest will not be satisfied again",
+ StringValue ("100ms"),
+ MakeTimeAccessor (&CcnxPit::m_PitEntryPruningTimout),
+ MakeTimeChecker ())
;
return tid;
@@ -83,7 +90,7 @@
m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events
// schedule even with new timeout
- m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
+ m_cleanupEvent = Simulator::Schedule (m_cleanupTimeout,
&CcnxPit::CleanExpired, this);
}
@@ -95,21 +102,25 @@
void CcnxPit::CleanExpired ()
{
- NS_LOG_LOGIC ("Cleaning PIT");
+ NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
Time now = Simulator::Now ();
-
+
+ uint32_t count = 0;
while( !empty() )
{
if( get<i_timestamp> ().front ().GetExpireTime () <= now ) // is the record stale?
{
get<i_timestamp> ().pop_front( );
+ count ++;
}
else
break; // nothing else to do. All later records will not be stale
}
-
+
+ // NS_LOG_LOGIC ("Cleaned " << count << " records. Total: " << size ());
// schedule next even
- m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
+
+ m_cleanupEvent = Simulator::Schedule (m_cleanupTimeout,
&CcnxPit::CleanExpired, this);
}
@@ -120,48 +131,46 @@
}
/*CcnxPitEntryContainer::type::iterator
-CcnxPit::Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face)
-{
- if( m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] )
- {
- // printf( "DEBUG: bucket overflow. Should not forward anything to interface %d\n", interest.interfaceIndex );
- return end();
- }
+ CcnxPit::Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face)
+ {
+ if( m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] )
+ {
+ // printf( "DEBUG: bucket overflow. Should not forward anything to interface %d\n", interest.interfaceIndex );
+ return end();
+ }
- CcnxPitEntryContainer::type::iterator entry = insert (end (),
- CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
- *fibEntry));
- return entry;
-}*/
+ CcnxPitEntryContainer::type::iterator entry = insert (end (),
+ CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
+ *fibEntry));
+ return entry;
+ }*/
-
-
bool
-CcnxPit::TryAddOutgoing(CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face)
+CcnxPit::TryAddOutgoing (CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face)
{
- NS_LOG_INFO ("Face has " << m_bucketsPerFace[face->GetId()] << " packets with max allowance " << maxBucketsPerFace[face->GetId()]);
+ NS_LOG_INFO ("Face has " << m_bucketsPerFace[face->GetId()] << " packets with max allowance " << maxBucketsPerFace[face->GetId()]);
- if((face->IsLocal() == false)
- && (m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] ))
- {
- NS_LOG_INFO("********LIMIT**************");
- return false;
- }
+ if((face->IsLocal() == false)
+ && (m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] ))
+ {
+ NS_LOG_INFO("********LIMIT**************");
+ return false;
+ }
- m_bucketsPerFace[face->GetId()] = m_bucketsPerFace[face->GetId()] + 1.0;
+ m_bucketsPerFace[face->GetId()] = m_bucketsPerFace[face->GetId()] + 1.0;
- NS_LOG_INFO(this->size());
- NS_LOG_INFO("before modify");
- NS_LOG_INFO(pitEntry->GetPrefix());
- modify (pitEntry, CcnxPitEntry::AddOutgoing(face));
- NS_LOG_INFO("after modify");
- return true;
+ NS_LOG_INFO(this->size());
+ NS_LOG_INFO("before modify");
+ NS_LOG_INFO(pitEntry->GetPrefix());
+ modify (pitEntry, CcnxPitEntry::AddOutgoing(face));
+ NS_LOG_INFO("after modify");
+ return true;
}
const CcnxPitEntry&
CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
{
- NS_LOG_FUNCTION_NOARGS ();
+ // NS_LOG_FUNCTION_NOARGS ();
CcnxPitEntryContainer::type::iterator entry =
get<i_prefix> ().find (header.GetName ());
@@ -172,50 +181,65 @@
return *entry;
}
-CcnxPitEntryContainer::type::iterator
-CcnxPit::Lookup (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator &outFibEntry)
+std::pair<CcnxPitEntryContainer::type::iterator,std::pair<bool, bool> >
+CcnxPit::Lookup (const CcnxInterestHeader &header)
{
NS_LOG_FUNCTION_NOARGS ();
NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
+ bool isDuplicate = false;
+ bool isNew = true;
+
CcnxPitEntryContainer::type::iterator entry =
get<i_prefix> ().find (header.GetName ());
- CcnxFibEntryContainer::type::iterator fibEntry = m_fib->LongestPrefixMatch (header);
- if (fibEntry == m_fib->end ())
- {
- NS_LOG_WARN ("FIB entry wasn't found. Creating an empty record");
- fibEntry = m_fib->insert (m_fib->end (), CcnxFibEntry (header.GetName ()));
- }
-
if (entry == end ())
- {
- NS_LOG_INFO("entry == end");
- NS_LOG_INFO(this->size());
- entry = insert (end (),
- CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
- *fibEntry));
- NS_LOG_INFO(this->size());
- }
- outFibEntry = fibEntry;
- return entry;
+ {
+ CcnxFibEntryContainer::type::iterator fibEntry = m_fib->LongestPrefixMatch (header);
+ NS_ASSERT_MSG (fibEntry != m_fib->end (),
+ "There should be at least default route set");
+
+ entry = insert (end (),
+ CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
+ Simulator::Now () +
+ (header.GetInterestLifetime ().IsZero ()?DEFAULT_INTEREST_LIFETIME:
+ header.GetInterestLifetime ())
+ *fibEntry));
+
+ // isDuplicate = false; // redundant
+ // isNew = true; // also redundant
+ }
+ else
+ {
+ isNew = false;
+ isDuplicate = entry->IsNonceSeen (header->GetNonce ());
+ }
+
+ if (!isDuplicate)
+ {
+ modify (entry, boost::bind(&CcnxPitEntry::AddSeenNonce, boost::lambda::_1, header->GetNonce ()));
+ }
+
+ return make_tuple (cref(*entry), isNew, isDuplicate);
}
+///////////////////////////////////////////////////////////////////////////////////////////
+
void
-CcnxPit::LeakBuckets( )
+CcnxPit::LeakBuckets ()
{
- for( PitBucketIterator it=m_bucketsPerFace.begin();
- it != m_bucketsPerFace.end();
- it++ )
+ for (PitBucketIterator it = m_bucketsPerFace.begin();
+ it != m_bucketsPerFace.end();
+ it++)
{
- it->second = std::max( 0.0, it->second - leakSize[it->first] );
+ it->second = std::max (0.0, it->second - leakSize[it->first]);
}
}
void
-CcnxPit::LeakBucket(Ptr<CcnxFace> face, int amount )
+CcnxPit::LeakBucket (Ptr<CcnxFace> face, int amount)
{
- m_bucketsPerFace[face->GetId()] = std::max( 0.0, m_bucketsPerFace[face->GetId()] - amount );
+ m_bucketsPerFace[face->GetId()] = std::max (0.0, m_bucketsPerFace[face->GetId()] - amount);
}
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index 16a3283..538e127 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -39,6 +39,7 @@
#include <map>
#include <iostream>
#include <algorithm>
+#include <boost/tuple/tuple.hpp>
namespace ns3 {
@@ -126,7 +127,8 @@
Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face);*/
bool
- TryAddOutgoing(CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face);
+ TryAddOutgoing(CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face);
+
/**
* \brief Find corresponding PIT entry for the given content name
* \param prefix Prefix for which to lookup the entry
@@ -139,10 +141,14 @@
/**
* \brief Find corresponding PIT entry for the given content name
* \param prefix Prefix for which to lookup the entry
- * \returns const reference to Pit entry. If record does not exist, it will be created
+ * \returns a tuple:
+ * get<0>: `const CcnxPitEntry&`: a valid PIT entry (if record does not exist, it will be created)
+ * get<1>: `bool`: true if a new entry was created
+ * get<2>: `bool`: true if a PIT entry exists and Nonce that present in header has been already seen
+ *
*/
- CcnxPitEntryContainer::type::iterator
- Lookup (const CcnxInterestHeader &header,CcnxFibEntryContainer::type::iterator &outFibEntry);
+ boost::tuple<const CcnxPitEntry&, bool, bool>
+ Lookup (const CcnxInterestHeader &header);
// remove a PIT entry
//void erase (const string &contentName);
@@ -175,6 +181,11 @@
*/
Time GetCleanupTimeout () const;
+ Time GetPitEntryPruningTimeout () const
+ {
+ return m_PitEntryPruningTimout;
+ }
+
/**
* \brief Set FIB table
*/
@@ -199,6 +210,7 @@
private:
Time m_cleanupTimeout; ///< \brief Configurable timeout of how often cleanup events are working
EventId m_cleanupEvent; ///< \brief Cleanup event
+ Time m_PitEntryPruningTimout;
Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
PitBucket m_bucketsPerFace; ///< \brief pending interface counter per face
diff --git a/model/ccnx-rit.cc b/model/ccnx-rit.cc
index 32c9ddb..2a1b7f0 100644
--- a/model/ccnx-rit.cc
+++ b/model/ccnx-rit.cc
@@ -119,7 +119,7 @@
m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events
// schedule even with new timeout
- m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
+ m_cleanupEvent = Simulator::Schedule (m_cleanupTimeout,
&CcnxRit::CleanExpired, this);
}
@@ -132,7 +132,7 @@
bool
CcnxRit::WasRecentlySatisfied (const CcnxInterestHeader &header)
{
- NS_LOG_FUNCTION_NOARGS ();
+ // NS_LOG_FUNCTION_NOARGS ();
std::pair<CcnxRitByNonce::type::iterator,CcnxRitByNonce::type::iterator>
entries = get<nonce> ().equal_range (header.GetNonce ());
@@ -153,7 +153,7 @@
void
CcnxRit::SetRecentlySatisfied (const CcnxInterestHeader &header)
{
- NS_LOG_FUNCTION_NOARGS ();
+ // NS_LOG_FUNCTION_NOARGS ();
NS_ASSERT_MSG (!WasRecentlySatisfied (header), "Duplicate recent interest should not be added to RIT");
get<timestamp> ().push_back (
@@ -166,30 +166,21 @@
void CcnxRit::CleanExpired ()
{
- // NS_LOG_LOGIC ("Cleaning RIT");
+ NS_LOG_LOGIC ("Cleaning RIT, total: " << size ());
Time now = Simulator::Now ();
-// #ifdef _DEBUG
-// uint32_t count = 0;
-// #endif
while( !empty() )
{
if( get<timestamp> ().front ().m_expireTime <= now ) // is the record stale?
{
get<timestamp> ().pop_front( );
-// #ifdef _DEBUG
-// count++;
-// #endif
}
else
break; // nothing else to do. All later records will not be stale
}
-// #ifdef _DEBUG
-// NS_LOG_DEBUG (count << " records cleaned");
-// #endif
// schedule next even
- m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
+ m_cleanupEvent = Simulator::Schedule (m_cleanupTimeout,
&CcnxRit::CleanExpired, this);
}