Merge remote-tracking branch 'git.irl/Ilya'
diff --git a/apps/ccnx-app.cc b/apps/ccnx-app.cc
new file mode 100644
index 0000000..7b9c2b9
--- /dev/null
+++ b/apps/ccnx-app.cc
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ccnx-app.h"
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+#include "ns3/ccnx.h"
+#include "ns3/ccnx-fib.h"
+#include "ns3/ccnx-local-face.h"
+
+NS_LOG_COMPONENT_DEFINE ("CcnxApp");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (CcnxApp);
+
+TypeId
+CcnxApp::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::CcnxApp")
+ .SetParent<Application> ()
+ .AddConstructor<CcnxApp> ()
+ ;
+ return tid;
+}
+
+CcnxApp::CcnxApp ()
+ : m_protocolHandler (0)
+ , m_active (false)
+ , m_face (0)
+{
+}
+
+CcnxApp::~CcnxApp ()
+{
+ StopApplication ();
+}
+
+void
+CcnxApp::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ StopApplication ();
+ Application::DoDispose ();
+}
+
+void
+CcnxApp::RegisterProtocolHandler (ProtocolHandler handler)
+{
+ m_protocolHandler = handler;
+}
+
+void
+CcnxApp::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
+{
+ NS_LOG_FUNCTION (this << interest);
+}
+
+void
+CcnxApp::OnNack (const Ptr<const CcnxInterestHeader> &interest)
+{
+ NS_LOG_FUNCTION (this << interest);
+}
+
+void
+CcnxApp::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+ const Ptr<const Packet> &payload)
+{
+ NS_LOG_FUNCTION (this << contentObject << payload);
+}
+
+// Application Methods
+void
+CcnxApp::StartApplication () // Called at time specified by Start
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT (m_active != true);
+ m_active = true;
+
+ NS_ASSERT_MSG (GetNode ()->GetObject<Ccnx> () != 0,
+ "Ccnx stack should be installed on the node " << GetNode ());
+
+ // step 1. Create a face
+ m_face = Create<CcnxLocalFace> (/*Ptr<CcnxApp> (this)*/this);
+
+ // step 2. Add face to the CCNx stack
+ GetNode ()->GetObject<Ccnx> ()->AddFace (m_face);
+
+ // step 3. Enable face
+ m_face->SetUp (true);
+}
+
+void
+CcnxApp::StopApplication () // Called at time specified by Stop
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (!m_active) return; //don't assert here, just return
+
+ NS_ASSERT (GetNode ()->GetObject<Ccnx> () != 0);
+
+ m_active = false;
+
+ // step 1. Disable face
+ m_face->SetUp (false);
+
+ // step 2. Remove face from CCNx stack
+ GetNode ()->GetObject<Ccnx> ()->RemoveFace (m_face);
+ GetNode ()->GetObject<CcnxFib> ()->RemoveFromAll (m_face);
+
+ // step 3. Destroy face
+ NS_ASSERT_MSG (m_face->GetReferenceCount ()==1,
+ "At this point, nobody else should have referenced this face, but we have "
+ << m_face->GetReferenceCount () << " references");
+ m_face = 0;
+}
+
+}
diff --git a/apps/ccnx-app.h b/apps/ccnx-app.h
new file mode 100644
index 0000000..f94018f
--- /dev/null
+++ b/apps/ccnx-app.h
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef CCNX_APP_H
+#define CCNX_APP_H
+
+#include "ns3/application.h"
+#include "ns3/ptr.h"
+#include "ns3/callback.h"
+
+namespace ns3
+{
+
+class Packet;
+class CcnxInterestHeader;
+class CcnxContentObjectHeader;
+class CcnxFace;
+
+/**
+ * @ingroup ccnx
+ * @brief Base class that all CCNx applications should be derived from.
+ *
+ * The class implements virtual calls onInterest, onNack, and onContentObject
+ */
+class CcnxApp: public Application
+{
+public:
+ typedef Callback<bool, const Ptr<const Packet>&> ProtocolHandler;
+
+ static TypeId GetTypeId ();
+
+ /**
+ * @brief Default constructor
+ */
+ CcnxApp ();
+ virtual ~CcnxApp ();
+
+ /**
+ * @brief Register lower layer callback (to send interests from the application)
+ */
+ void
+ RegisterProtocolHandler (ProtocolHandler handler);
+
+ /**
+ * @brief Method that will be called every time new Interest arrives
+ * @param interest Interest header
+ */
+ virtual void
+ OnInterest (const Ptr<const CcnxInterestHeader> &interest);
+
+ /**
+ * @brief Method that will be called every time new NACK arrives
+ * @param interest Interest header
+ */
+ virtual void
+ OnNack (const Ptr<const CcnxInterestHeader> &interest);
+
+ /**
+ * @brief Method that will be called every time new ContentObject arrives
+ * @param contentObject ContentObject header
+ * @param payload payload (potentially virtual) of the ContentObject packet
+ */
+ virtual void
+ OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+ const Ptr<const Packet> &payload);
+
+protected:
+ virtual void
+ DoDispose ();
+
+ // inherited from Application base class.
+ virtual void
+ StartApplication (); // Called at time specified by Start
+
+ virtual void
+ StopApplication (); // Called at time specified by Stop
+
+protected:
+ ProtocolHandler m_protocolHandler;
+ bool m_active;
+ Ptr<CcnxFace> m_face; // local face that is created
+};
+
+} // namespace ns3
+
+#endif // CCNX_APP_H
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 8352212..dc54f92 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -20,11 +20,21 @@
#include "ccnx-consumer.h"
#include "ns3/ptr.h"
-#include "ns3/ccnx-local-face.h"
-#include "ns3/ccnx.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
#include "ns3/callback.h"
+#include "ns3/string.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+
+#include "ns3/ccnx.h"
+#include "ns3/ccnx-local-face.h"
+#include "ns3/ccnx-interest-header.h"
#include "ns3/ccnx-content-object-header.h"
+#include <boost/ref.hpp>
+
NS_LOG_COMPONENT_DEFINE ("CcnxConsumer");
namespace ns3
@@ -35,172 +45,121 @@
TypeId
CcnxConsumer::GetTypeId (void)
{
- static TypeId tid = TypeId ("ns3::CcnxConsumer")
- .SetParent<Application> ()
- .AddConstructor<CcnxConsumer> ()
- .AddAttribute ("OffTime", "Time interval between packets",
- TimeValue (Seconds (0.001)),
- MakeTimeAccessor (&CcnxConsumer::m_offTime),
- MakeTimeChecker ())
- .AddAttribute ("InterestName","CcnxName of the Interest (use CcnxNameComponents)",
- CcnxNameComponentsValue (),
- MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_interestName),
- MakeCcnxNameComponentsChecker ())
- .AddAttribute ("LifeTime", "LifeTime fo interest packet",
- TimeValue (Seconds (0)),
- MakeTimeAccessor (&CcnxConsumer::m_interestLifeTime),
- MakeTimeChecker ())
- .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
- IntegerValue(-1),
- MakeIntegerAccessor(&CcnxConsumer::m_minSuffixComponents),
- MakeIntegerChecker<int32_t>())
- .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
- IntegerValue(-1),
- MakeIntegerAccessor(&CcnxConsumer::m_maxSuffixComponents),
- MakeIntegerChecker<int32_t>())
- .AddAttribute ("ChildSelector", "ChildSelector",
- BooleanValue(false),
- MakeBooleanAccessor(&CcnxConsumer::m_childSelector),
- MakeBooleanChecker())
- .AddAttribute ("Exclude", "only simple name matching is supported (use CcnxNameComponents)",
- CcnxNameComponentsValue (),
- MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_exclude),
- MakeCcnxNameComponentsChecker ())
- .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
- UintegerValue(1),
- MakeUintegerAccessor(&CcnxConsumer::m_initialNonce),
- MakeUintegerChecker<uint32_t>())
- .AddTraceSource ("InterestTrace", "Interests that were sent",
- MakeTraceSourceAccessor (&CcnxConsumer::m_interestsTrace))
- .AddTraceSource ("ContentObjectTrace", "ContentObjects that were received",
- MakeTraceSourceAccessor (&CcnxConsumer::m_contentObjectsTrace))
- ;
+ static TypeId tid = TypeId ("ns3::CcnxConsumer")
+ .SetParent<Application> ()
+ .AddConstructor<CcnxConsumer> ()
+ .AddAttribute ("OffTime", "Time interval between packets",
+ StringValue ("100ms"),
+ MakeTimeAccessor (&CcnxConsumer::m_offTime),
+ MakeTimeChecker ())
+ .AddAttribute ("InterestName","CcnxName of the Interest (use CcnxNameComponents)",
+ StringValue ("/"),
+ MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_interestName),
+ MakeCcnxNameComponentsChecker ())
+ .AddAttribute ("LifeTime", "LifeTime fo interest packet",
+ StringValue ("2s"),
+ MakeTimeAccessor (&CcnxConsumer::m_interestLifeTime),
+ MakeTimeChecker ())
+ .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
+ IntegerValue(-1),
+ MakeIntegerAccessor(&CcnxConsumer::m_minSuffixComponents),
+ MakeIntegerChecker<int32_t>())
+ .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
+ IntegerValue(-1),
+ MakeIntegerAccessor(&CcnxConsumer::m_maxSuffixComponents),
+ MakeIntegerChecker<int32_t>())
+ .AddAttribute ("ChildSelector", "ChildSelector",
+ BooleanValue(false),
+ MakeBooleanAccessor(&CcnxConsumer::m_childSelector),
+ MakeBooleanChecker())
+ .AddAttribute ("Exclude", "only simple name matching is supported (use CcnxNameComponents)",
+ CcnxNameComponentsValue (),
+ MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_exclude),
+ MakeCcnxNameComponentsChecker ())
+ // .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
+ // UintegerValue(1),
+ // MakeUintegerAccessor(&CcnxConsumer::m_initialNonce),
+ // MakeUintegerChecker<uint32_t>())
+ // .AddTraceSource ("InterestTrace", "Interests that were sent",
+ // MakeTraceSourceAccessor (&CcnxConsumer::m_interestsTrace))
+ // .AddTraceSource ("ContentObjectTrace", "ContentObjects that were received",
+ // MakeTraceSourceAccessor (&CcnxConsumer::m_contentObjectsTrace))
+ ;
- return tid;
+ return tid;
}
CcnxConsumer::CcnxConsumer ()
- : m_seq (0)
+ : m_rand (0, std::numeric_limits<uint32_t>::max ())
+ , m_seq (0)
{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-CcnxConsumer::~CcnxConsumer()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-CcnxConsumer::DoDispose (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- Application::DoDispose ();
+ NS_LOG_FUNCTION_NOARGS ();
}
// Application Methods
void
CcnxConsumer::StartApplication () // Called at time specified by Start
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION_NOARGS ();
- NS_ASSERT_MSG (m_face == 0, "Face should not exist");
- m_face = Create<CcnxLocalFace> ();
-
- // step 1. Set up forwarding from face to application
- m_face->SetNode (GetNode ());
- m_face->SetContentObjectHandler (MakeCallback (&CcnxConsumer::OnContentObject, this));
-
- // step 2. Set up forwarding to and from ccnx
- NS_ASSERT_MSG (GetNode ()->GetObject<Ccnx> () !=0,
- "Ccnx stack should be installed on the node " << GetNode ());
- GetNode ()->GetObject<Ccnx> ()->AddFace (m_face);
-
- // step 3. Enable face
- m_face->SetUp ();
-
- // Send first packet immediately
- m_sendEvent = Simulator::Schedule (Seconds(0.0), &CcnxConsumer::SendPacket, this);
+ // do base stuff
+ CcnxApp::StartApplication ();
+
+ // schedule periodic packet generation
+ m_sendEvent = Simulator::Schedule (Seconds(0.0), &CcnxConsumer::SendPacket, this);
}
void
CcnxConsumer::StopApplication () // Called at time specified by Stop
{
- NS_LOG_FUNCTION_NOARGS ();
-
- CancelEvents ();
+ NS_LOG_FUNCTION_NOARGS ();
- // step 1. Disable face
- m_face->SetDown ();
+ // cancel periodic packet generation
+ Simulator::Cancel (m_sendEvent);
- // step 2. Remove face from ccnx stack
- GetNode ()->GetObject<Ccnx> ()->RemoveFace (m_face);
-
- // step 3. Disable callbacks
- m_face->SetContentObjectHandler (MakeNullCallback<void,
- const Ptr<const CcnxContentObjectHeader> &,
- const Ptr<const Packet> &> ());
-}
-
-void
-CcnxConsumer::CancelEvents ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- Simulator::Cancel (m_sendEvent);
+ // cleanup base stuff
+ CcnxApp::StopApplication ();
}
void
CcnxConsumer::SendPacket ()
{
- NS_LOG_FUNCTION_NOARGS ();
- NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
+ NS_LOG_FUNCTION_NOARGS ();
- UniformVariable rand(1, std::numeric_limits<uint32_t>::max ());
- uint32_t randomNonce = rand.GetValue();
-
- CcnxInterestHeader interestHeader;
- interestHeader.SetNonce(randomNonce);
-
- Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> (m_interestName);
- std::ostringstream os;
- os << m_seq++;
- (*name) (os.str ());
-
- interestHeader.SetName (name);
- interestHeader.SetInterestLifetime(m_interestLifeTime);
- interestHeader.SetChildSelector(m_childSelector);
- interestHeader.SetExclude(Create<CcnxNameComponents> (m_exclude));
- interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
- interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
-
- NS_LOG_INFO ("Interest: \n" << interestHeader);
+ //
+ Ptr<CcnxNameComponents> nameWithSequence = Create<CcnxNameComponents> (m_interestName);
+ (*nameWithSequence) (m_seq++);
+ //
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (interestHeader);
+ CcnxInterestHeader interestHeader;
+ interestHeader.SetNonce (m_rand.GetValue ());
+ interestHeader.SetName (nameWithSequence);
+ interestHeader.SetInterestLifetime (m_interestLifeTime);
+ interestHeader.SetChildSelector (m_childSelector);
+ if (m_exclude.size ()>0)
+ {
+ interestHeader.SetExclude (Create<CcnxNameComponents> (m_exclude));
+ }
+ interestHeader.SetMaxSuffixComponents (m_maxSuffixComponents);
+ interestHeader.SetMinSuffixComponents (m_minSuffixComponents);
- m_face->ReceiveFromApplication (packet);
+ NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
+
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (interestHeader);
+
+ m_protocolHandler (packet);
- m_interestsTrace (m_face,packet);
-
- NS_LOG_INFO("time = " << m_offTime);
- m_sendEvent = Simulator::Schedule (m_offTime, &CcnxConsumer::SendPacket, this);
+ m_sendEvent = Simulator::Schedule (m_offTime, &CcnxConsumer::SendPacket, this);
}
-
-// void
-// CcnxConsumer::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
-// {
-// }
void
CcnxConsumer::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
const Ptr<const Packet> &payload)
{
- // do stuff
- NS_LOG_FUNCTION ("Received contentObject " << contentObject );
- NS_LOG_INFO ("Preved!");
- m_contentObjectsTrace (m_face,payload);
+ NS_LOG_FUNCTION (this << contentObject << payload);
+
+ NS_LOG_INFO ("Received content object: " << boost::cref(*contentObject));
}
-
-}
+} // namespace ns3
diff --git a/apps/ccnx-consumer.h b/apps/ccnx-consumer.h
index 16dbaf7..792c829 100644
--- a/apps/ccnx-consumer.h
+++ b/apps/ccnx-consumer.h
@@ -21,76 +21,47 @@
#ifndef CCNX_CONSUMER_H
#define CCNX_CONSUMER_H
-#include "ns3/application.h"
-#include "ns3/log.h"
+#include "ccnx-app.h"
#include "ns3/random-variable.h"
-#include "ns3/nstime.h"
-#include "ns3/event-id.h"
-#include "ns3/ptr.h"
-#include "ns3/simulator.h"
-#include "ns3/ccnx-interest-header.h"
-#include "ns3/ccnx-local-face.h"
#include "ns3/ccnx-name-components.h"
-#include "ns3/packet.h"
-#include "ns3/boolean.h"
-#include "ns3/integer.h"
-#include "ns3/uinteger.h"
-#include "ns3/pointer.h"
-#include "ns3/traced-callback.h"
-#include "ns3/ccnx-header-helper.h"
-
-#include "ns3/packet.h"
-#include "ns3/header.h"
namespace ns3
{
-class CcnxConsumer: public Application
+class CcnxConsumer: public CcnxApp
{
public:
static TypeId GetTypeId ();
CcnxConsumer ();
- virtual ~CcnxConsumer ();
void OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
const Ptr<const Packet> &payload);
-
+
protected:
- virtual void DoDispose (void);
+ // from CcnxApp
+ virtual void
+ StartApplication ();
+
+ virtual void
+ StopApplication ();
private:
- // inherited from Application base class.
- virtual void StartApplication (void); // Called at time specified by Start
- virtual void StopApplication (void); // Called at time specified by Stop
-
//helpers
- void CancelEvents ();
-
- // Event handlers
- // void StartSending ();
- // void StopSending ();
void SendPacket ();
- //typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
private:
- TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_interestsTrace;
- TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_contentObjectsTrace;
+ UniformVariable m_rand;
+ uint32_t m_seq;
+ EventId m_sendEvent; // Eventid of pending "send packet" event
- Time m_offTime;
+ Time m_offTime;
CcnxNameComponents m_interestName;
- Time m_interestLifeTime;
- int32_t m_minSuffixComponents;
- int32_t m_maxSuffixComponents;
- bool m_childSelector;
+ Time m_interestLifeTime;
+ int32_t m_minSuffixComponents;
+ int32_t m_maxSuffixComponents;
+ bool m_childSelector;
CcnxNameComponents m_exclude;
- uint32_t m_initialNonce;
-
- EventId m_sendEvent; // Eventid of pending "send packet" event
- TypeId m_tid;
- Ptr<CcnxLocalFace> m_face;
-
- uint32_t m_seq;
};
} // namespace ns3
diff --git a/apps/ccnx-interest-sender.cc b/apps/ccnx-interest-sender.cc
index bcf3d76..d110978 100644
--- a/apps/ccnx-interest-sender.cc
+++ b/apps/ccnx-interest-sender.cc
@@ -1,161 +1,160 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
+// /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+// /*
+// * Copyright (c) 2011 University of California, Los Angeles
+// *
+// * This program is free software; you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License version 2 as
+// * published by the Free Software Foundation;
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program; if not, write to the Free Software
+// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// *
+// * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+// */
-#include "ccnx-interest-sender.h"
+// #include "ccnx-interest-sender.h"
-NS_LOG_COMPONENT_DEFINE ("CcnxInterestSender");
+// NS_LOG_COMPONENT_DEFINE ("CcnxInterestSender");
-namespace ns3
-{
+// namespace ns3
+// {
-NS_OBJECT_ENSURE_REGISTERED (CcnxInterestSender);
+// NS_OBJECT_ENSURE_REGISTERED (CcnxInterestSender);
-TypeId
-CcnxInterestSender::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::CcnxInterestSender")
- .SetParent<Application> ()
- .AddConstructor<CcnxInterestSender> ()
- .AddAttribute ("OffTime", "Time interval between packets",
- TimeValue (Seconds (0.1)),
- MakeTimeAccessor (&CcnxInterestSender::m_offTime),
- MakeTimeChecker ())
- // Alex: this is incorrect. SetNode call is not called if face is created using this accessor
- // .AddAttribute ("Face","Local face to be used",
- // PointerValue (CreateObject<CcnxLocalFace> ()),
- // MakePointerAccessor (&CcnxInterestSender::m_face),
- // MakePointerChecker<CcnxLocalFace> ())
- .AddAttribute ("NameComponents","CcnxName of the Interest (use CcnxNameComponents)",
- CcnxNameComponentsValue (CcnxNameComponents (/* root */)),
- MakeCcnxNameComponentsAccessor (&CcnxInterestSender::m_interestName),
- MakeCcnxNameComponentsChecker ())
- .AddAttribute ("LifeTime", "LifeTime fo interest packet",
- TimeValue (Seconds (4.0)),
- MakeTimeAccessor (&CcnxInterestSender::m_interestLifeTime),
- MakeTimeChecker ())
- .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
- IntegerValue(-1),
- MakeIntegerAccessor(&CcnxInterestSender::m_minSuffixComponents),
- MakeIntegerChecker<int32_t>())
- .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
- IntegerValue(-1),
- MakeIntegerAccessor(&CcnxInterestSender::m_maxSuffixComponents),
- MakeIntegerChecker<int32_t>())
- .AddAttribute ("ChildSelector", "ChildSelector",
- BooleanValue(false),
- MakeBooleanAccessor(&CcnxInterestSender::m_childSelector),
- MakeBooleanChecker())
- .AddAttribute ("Exclude","only simple name matching is supported (use CcnxNameComponents)",
- CcnxNameComponentsValue (CcnxNameComponents(/* root */)),
- MakeCcnxNameComponentsAccessor (&CcnxInterestSender::m_exclude),
- MakeCcnxNameComponentsChecker ())
- .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
- UintegerValue(1),
- MakeUintegerAccessor(&CcnxInterestSender::m_initialNonce),
- MakeUintegerChecker<uint32_t>())
- ;
- /*
- .AddAttribute ("NoiseModel",
- "A pointer to the model of the channel ambient noise.",
- PointerValue (CreateObject<UanNoiseModelDefault> ()),
- MakePointerAccessor (&UanChannel::m_noise),
- MakePointerChecker<UanNoiseModel> ())*/
- return tid;
-}
+// TypeId
+// CcnxInterestSender::GetTypeId (void)
+// {
+// static TypeId tid = TypeId ("ns3::CcnxInterestSender")
+// .SetParent<Application> ()
+// .AddConstructor<CcnxInterestSender> ()
+// .AddAttribute ("OffTime", "Time interval between packets",
+// TimeValue (Seconds (0.1)),
+// MakeTimeAccessor (&CcnxInterestSender::m_offTime),
+// MakeTimeChecker ())
+// // Alex: this is incorrect. SetNode call is not called if face is created using this accessor
+// // .AddAttribute ("Face","Local face to be used",
+// // PointerValue (CreateObject<CcnxLocalFace> ()),
+// // MakePointerAccessor (&CcnxInterestSender::m_face),
+// // MakePointerChecker<CcnxLocalFace> ())
+// .AddAttribute ("NameComponents","CcnxName of the Interest (use CcnxNameComponents)",
+// CcnxNameComponentsValue (CcnxNameComponents (/* root */)),
+// MakeCcnxNameComponentsAccessor (&CcnxInterestSender::m_interestName),
+// MakeCcnxNameComponentsChecker ())
+// .AddAttribute ("LifeTime", "LifeTime fo interest packet",
+// TimeValue (Seconds (4.0)),
+// MakeTimeAccessor (&CcnxInterestSender::m_interestLifeTime),
+// MakeTimeChecker ())
+// .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
+// IntegerValue(-1),
+// MakeIntegerAccessor(&CcnxInterestSender::m_minSuffixComponents),
+// MakeIntegerChecker<int32_t>())
+// .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
+// IntegerValue(-1),
+// MakeIntegerAccessor(&CcnxInterestSender::m_maxSuffixComponents),
+// MakeIntegerChecker<int32_t>())
+// .AddAttribute ("ChildSelector", "ChildSelector",
+// BooleanValue(false),
+// MakeBooleanAccessor(&CcnxInterestSender::m_childSelector),
+// MakeBooleanChecker())
+// .AddAttribute ("Exclude","only simple name matching is supported (use CcnxNameComponents)",
+// CcnxNameComponentsValue (CcnxNameComponents(/* root */)),
+// MakeCcnxNameComponentsAccessor (&CcnxInterestSender::m_exclude),
+// MakeCcnxNameComponentsChecker ())
+// .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
+// UintegerValue(1),
+// MakeUintegerAccessor(&CcnxInterestSender::m_initialNonce),
+// MakeUintegerChecker<uint32_t>())
+// ;
+// /*
+// .AddAttribute ("NoiseModel",
+// "A pointer to the model of the channel ambient noise.",
+// PointerValue (CreateObject<UanNoiseModelDefault> ()),
+// MakePointerAccessor (&UanChannel::m_noise),
+// MakePointerChecker<UanNoiseModel> ())*/
+// return tid;
+// }
-CcnxInterestSender::CcnxInterestSender ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
+// CcnxInterestSender::CcnxInterestSender ()
+// {
+// NS_LOG_FUNCTION_NOARGS ();
+// }
-CcnxInterestSender::~CcnxInterestSender()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
+// CcnxInterestSender::~CcnxInterestSender()
+// {
+// NS_LOG_FUNCTION_NOARGS ();
+// }
-void
-CcnxInterestSender::DoDispose (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
+// void
+// CcnxInterestSender::DoDispose (void)
+// {
+// NS_LOG_FUNCTION_NOARGS ();
- Application::DoDispose ();
-}
+// Application::DoDispose ();
+// }
-// Application Methods
-void
-CcnxInterestSender::StartApplication () // Called at time specified by Start
-{
- NS_LOG_FUNCTION_NOARGS ();
- ScheduleNextTx();
-}
+// // Application Methods
+// void
+// CcnxInterestSender::StartApplication () // Called at time specified by Start
+// {
+// NS_LOG_FUNCTION_NOARGS ();
+// ScheduleNextTx();
+// }
-void
-CcnxInterestSender::StopApplication () // Called at time specified by Stop
-{
- NS_LOG_FUNCTION_NOARGS ();
+// void
+// CcnxInterestSender::StopApplication () // Called at time specified by Stop
+// {
+// NS_LOG_FUNCTION_NOARGS ();
- CancelEvents ();
-}
+// CancelEvents ();
+// }
-void
-CcnxInterestSender::CancelEvents ()
-{
- NS_LOG_FUNCTION_NOARGS ();
+// void
+// CcnxInterestSender::CancelEvents ()
+// {
+// NS_LOG_FUNCTION_NOARGS ();
- Simulator::Cancel (m_sendEvent);
-}
+// Simulator::Cancel (m_sendEvent);
+// }
-void
-CcnxInterestSender::ScheduleNextTx ()
-{
- NS_LOG_FUNCTION_NOARGS ();
+// void
+// CcnxInterestSender::ScheduleNextTx ()
+// {
+// NS_LOG_FUNCTION_NOARGS ();
- Time nextTime = Seconds(m_offTime);
- m_sendEvent = Simulator::Schedule (nextTime, &CcnxInterestSender::SendPacket, this);
-}
+// Time nextTime = Seconds(m_offTime);
+// m_sendEvent = Simulator::Schedule (nextTime, &CcnxInterestSender::SendPacket, this);
+// }
-void
-CcnxInterestSender::SendPacket ()
-{
- NS_LOG_FUNCTION_NOARGS ();
- // NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
+// void
+// CcnxInterestSender::SendPacket ()
+// {
+// NS_LOG_FUNCTION_NOARGS ();
+// // NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
- uint32_t randomNonce = UniformVariable().GetInteger(1, std::numeric_limits<uint32_t>::max ());
- CcnxInterestHeader interestHeader;
- interestHeader.SetNonce(randomNonce);
- //const Ptr<CcnxNameComponents> name = Create<CcnxNameComponents>(m_interestName);
- interestHeader.SetName(Create<CcnxNameComponents> (m_interestName)); //making a copy of name
- interestHeader.SetInterestLifetime(m_interestLifeTime);
- interestHeader.SetChildSelector(m_childSelector);
- //const Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents>(m_exclude);
- interestHeader.SetExclude(Create<CcnxNameComponents> (m_exclude));
- interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
- interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
+// uint32_t randomNonce = UniformVariable().GetInteger(1, std::numeric_limits<uint32_t>::max ());
+// CcnxInterestHeader interestHeader;
+// interestHeader.SetNonce(randomNonce);
+// //const Ptr<CcnxNameComponents> name = Create<CcnxNameComponents>(m_interestName);
+// interestHeader.SetName(Create<CcnxNameComponents> (m_interestName)); //making a copy of name
+// interestHeader.SetInterestLifetime(m_interestLifeTime);
+// interestHeader.SetChildSelector(m_childSelector);
+// //const Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents>(m_exclude);
+// interestHeader.SetExclude(Create<CcnxNameComponents> (m_exclude));
+// interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
+// interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (interestHeader);
+// Ptr<Packet> packet = Create<Packet> ();
+// packet->AddHeader (interestHeader);
- m_face->Send(packet);
+// m_face->Send(packet);
- ScheduleNextTx();
-}
-
+// ScheduleNextTx();
+// }
-}
+// }
diff --git a/apps/ccnx-interest-sender.h b/apps/ccnx-interest-sender.h
index ad8de28..cbb54ad 100644
--- a/apps/ccnx-interest-sender.h
+++ b/apps/ccnx-interest-sender.h
@@ -1,106 +1,106 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
+// /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+// /*
+// * Copyright (c) 2011 University of California, Los Angeles
+// *
+// * This program is free software; you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License version 2 as
+// * published by the Free Software Foundation;
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program; if not, write to the Free Software
+// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// *
+// * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+// */
-#include "ns3/application.h"
-#include "ns3/log.h"
-#include "ns3/random-variable.h"
-#include "ns3/nstime.h"
-#include "ns3/event-id.h"
-#include "ns3/ptr.h"
-#include "ns3/simulator.h"
-#include "ns3/ccnx-interest-header.h"
-#include "ns3/ccnx-local-face.h"
-#include "ns3/ccnx-name-components.h"
-#include "ns3/packet.h"
-#include "ns3/boolean.h"
-#include "ns3/integer.h"
-#include "ns3/uinteger.h"
-#include "ns3/random-variable.h"
-#include <limits>
-#include "ns3/pointer.h"
+// #include "ns3/application.h"
+// #include "ns3/log.h"
+// #include "ns3/random-variable.h"
+// #include "ns3/nstime.h"
+// #include "ns3/event-id.h"
+// #include "ns3/ptr.h"
+// #include "ns3/simulator.h"
+// #include "ns3/ccnx-interest-header.h"
+// #include "ns3/ccnx-local-face.h"
+// #include "ns3/ccnx-name-components.h"
+// #include "ns3/packet.h"
+// #include "ns3/boolean.h"
+// #include "ns3/integer.h"
+// #include "ns3/uinteger.h"
+// #include "ns3/random-variable.h"
+// #include <limits>
+// #include "ns3/pointer.h"
-namespace ns3
-{
+// namespace ns3
+// {
-class Socket;
+// class Socket;
-class CcnxInterestSender: public Application
-{
-public:
- static TypeId GetTypeId (void);
+// class CcnxInterestSender: public Application
+// {
+// public:
+// static TypeId GetTypeId (void);
- CcnxInterestSender ();
+// CcnxInterestSender ();
- virtual ~CcnxInterestSender ();
+// virtual ~CcnxInterestSender ();
-protected:
- virtual void DoDispose (void);
-private:
- // inherited from Application base class.
- virtual void StartApplication (void); // Called at time specified by Start
- virtual void StopApplication (void); // Called at time specified by Stop
+// protected:
+// virtual void DoDispose (void);
+// private:
+// // inherited from Application base class.
+// virtual void StartApplication (void); // Called at time specified by Start
+// virtual void StopApplication (void); // Called at time specified by Stop
- //Time m_onTime;
- Time m_offTime;
- CcnxNameComponents m_interestName;
+// //Time m_onTime;
+// Time m_offTime;
+// CcnxNameComponents m_interestName;
- Time m_interestLifeTime;
- int32_t m_minSuffixComponents;
- int32_t m_maxSuffixComponents;
- bool m_childSelector;
- CcnxNameComponents m_exclude;
- uint32_t m_initialNonce;
+// Time m_interestLifeTime;
+// int32_t m_minSuffixComponents;
+// int32_t m_maxSuffixComponents;
+// bool m_childSelector;
+// CcnxNameComponents m_exclude;
+// uint32_t m_initialNonce;
- //EventId m_startStopEvent; // Event id for next start or stop event
- EventId m_sendEvent; // Eventid of pending "send packet" event
- TypeId m_tid;
- Ptr<CcnxLocalFace> m_face;
+// //EventId m_startStopEvent; // Event id for next start or stop event
+// EventId m_sendEvent; // Eventid of pending "send packet" event
+// TypeId m_tid;
+// Ptr<CcnxLocalFace> m_face;
- //helpers
- void CancelEvents ();
+// //helpers
+// void CancelEvents ();
- void Construct (Ptr<Node> n,
- std::string tid,
- const Time& offtime,
- Ptr<CcnxLocalFace> face,
- Ptr<CcnxNameComponents> nameComponents,
- const Time& lifetime,
- const int32_t& minSuffixComponents,
- const int32_t& maxSuffixComponents,
- const bool childSelector,
- Ptr<CcnxNameComponents> exclude,
- const uint32_t& initialNonce
- );
+// void Construct (Ptr<Node> n,
+// std::string tid,
+// const Time& offtime,
+// Ptr<CcnxLocalFace> face,
+// Ptr<CcnxNameComponents> nameComponents,
+// const Time& lifetime,
+// const int32_t& minSuffixComponents,
+// const int32_t& maxSuffixComponents,
+// const bool childSelector,
+// Ptr<CcnxNameComponents> exclude,
+// const uint32_t& initialNonce
+// );
- // Event handlers
- void StartSending ();
- void StopSending ();
- void SendPacket ();
+// // Event handlers
+// void StartSending ();
+// void StopSending ();
+// void SendPacket ();
-private:
- void ScheduleNextTx ();
- //void ScheduleStartEvent ();
- //void ScheduleStopEvent ();
- void ConnectionSucceeded (Ptr<Socket>);
- void ConnectionFailed (Ptr<Socket>);
- void Ignore (Ptr<Socket>);
+// private:
+// void ScheduleNextTx ();
+// //void ScheduleStartEvent ();
+// //void ScheduleStopEvent ();
+// void ConnectionSucceeded (Ptr<Socket>);
+// void ConnectionFailed (Ptr<Socket>);
+// void Ignore (Ptr<Socket>);
-};
-}
+// };
+// }
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index d320a2d..844acd4 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -16,202 +16,97 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "ccnx-producer.h"
+#include "ns3/log.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/packet.h"
+#include "ns3/ccnx-local-face.h"
+#include "ns3/ccnx-fib.h"
+
+#include <boost/ref.hpp>
NS_LOG_COMPONENT_DEFINE ("CcnxProducer");
namespace ns3
{
-
+
NS_OBJECT_ENSURE_REGISTERED (CcnxProducer);
TypeId
CcnxProducer::GetTypeId (void)
{
- static TypeId tid = TypeId ("ns3::CcnxProducer")
- .SetParent<Application> ()
+ static TypeId tid = TypeId ("ns3::CcnxProducer")
+ .SetParent<CcnxApp> ()
.AddConstructor<CcnxProducer> ()
- /*.AddAttribute ("Capacity", "Capacity of the ContentStore",
- UintegerValue(100),
- MakeUintegerAccessor(&CcnxProducer::m_storeCapacity),
- MakeUintegerChecker<uint32_t>())*/
.AddAttribute ("Prefix","Prefix, for which producer has the data",
- CcnxNameComponentsValue (),
+ StringValue ("/"),
MakeCcnxNameComponentsAccessor (&CcnxProducer::m_prefix),
MakeCcnxNameComponentsChecker ())
.AddAttribute ("PayloadSize", "Virtual payload size for Content packets",
- UintegerValue(100),
+ UintegerValue (1024),
MakeUintegerAccessor(&CcnxProducer::m_virtualPayloadSize),
MakeUintegerChecker<uint32_t>())
- .AddTraceSource ("InterestTrace", "Interests that were received",
- MakeTraceSourceAccessor (&CcnxProducer::m_interestsTrace))
- .AddTraceSource ("ContentObjectTrace", "ContentObjects that were sent",
- MakeTraceSourceAccessor (&CcnxProducer::m_contentObjectsTrace))
+ // .AddTraceSource ("InterestTrace", "Interests that were received",
+ // MakeTraceSourceAccessor (&CcnxProducer::m_interestsTrace))
+ // .AddTraceSource ("ContentObjectTrace", "ContentObjects that were sent",
+ // MakeTraceSourceAccessor (&CcnxProducer::m_contentObjectsTrace))
;
- return tid;
+ return tid;
}
CcnxProducer::CcnxProducer ()
{
- NS_LOG_FUNCTION_NOARGS ();
+ // NS_LOG_FUNCTION_NOARGS ();
}
-
-CcnxProducer::~CcnxProducer()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-CcnxProducer::DoDispose (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- Application::DoDispose ();
-}
-
- // Application Methods
-void
-CcnxProducer::StartApplication () // Called at time specified by Start
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NS_ASSERT_MSG (m_face == 0, "Face should not exist");
- m_face = Create<CcnxLocalFace> ();
-
- // step 1. Set up forwarding from face to application
- m_face->SetNode (GetNode ());
- m_face->SetInterestHandler (MakeCallback (&CcnxProducer::OnInterest, this));
-
- // step 2. Set up forwarding to and from ccnx
- NS_ASSERT_MSG (GetNode ()->GetObject<Ccnx> () !=0,
- "Ccnx stack should be installed on the node " << GetNode ());
- GetNode ()->GetObject<Ccnx> ()->AddFace (m_face);
- //Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
- GetNode ()->GetObject<Ccnx> ()->GetObject<CcnxFib> ()->Add(m_prefix, m_face, 0);
- // step 3. Enable face
- m_face->SetUp ();
-}
-
-void
-CcnxProducer::StopApplication () // Called at time specified by Stop
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-CcnxProducer::OnInterest(const Ptr<const CcnxInterestHeader> &interest)
-{
- NS_LOG_FUNCTION (this);
-
-
-
- //Ptr<Packet> data = Lookup (interest);
-
-
-
- Ptr<Packet> incomingPacket = Create<Packet>(m_virtualPayloadSize);
- incomingPacket->AddHeader (*interest);
- m_interestsTrace(m_face,incomingPacket);
-
-
- static CcnxContentObjectTail tail; ///< \internal for optimization purposes
- Ptr<Packet> outgoingPacket = Create<Packet> (m_virtualPayloadSize);
- Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader>();
- header->SetName(Create<CcnxNameComponents>(interest->GetName()));
- outgoingPacket->AddHeader(*header);
- outgoingPacket->AddTrailer (tail);
-
- m_contentObjectsTrace(m_face,outgoingPacket);
-
- m_face->ReceiveFromApplication(outgoingPacket);
-
-}
-
-void
-CcnxProducer::CancelEvents ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- // Simulator::Cancel (m_sendEvent);
-}
-
-CcnxNameComponents
-CcnxProducer::GetPrefix() const
-{
- return m_prefix;
-}
-
-/*uint32_t
-CcnxProducer::GetStoreCapacity()
-{
- return m_storeCapacity;
-}
-
+// inherited from Application base class.
void
-CcnxProducer::SetStoreCapacity(uint32_t capacity)
-{
- m_storeCapacity = capacity;
-}
- */
-/*void
-CcnxProducer::HandlePacket(const Ptr<CcnxFace> &face, const Ptr<const Packet> &packet)
-{
- uint8_t type[2];
- uint32_t read = packet->CopyData (type,2);
- if (read!=2)
- {
- NS_LOG_INFO ("Unknown CcnxPacket");
- return;
- }
-
- if (type[0] == INTEREST_BYTE0 && type[1] == INTEREST_BYTE1)
- {
- m_interestsTrace(face,packet);
- }
- else if (type[0] == CONTENT_OBJECT_BYTE0 && type[1] == CONTENT_OBJECT_BYTE1)
- {
- m_contentObjectsTrace(face,packet);
- }
-}*/
-
-/*Ptr<Packet>
-CcnxProducer::Lookup (Ptr<const CcnxInterestHeader> interest)
+CcnxProducer::StartApplication ()
{
NS_LOG_FUNCTION_NOARGS ();
- DataStoreContainer::type::iterator it = m_availableData.get<i_prefix> ().find (interest->GetName ());
-
- if (it != m_availableData.end ())
- {
- // return fully formed CCNx packet
- return it->GetFullyFormedCcnxPacket ();
- }
-
- return 0;
-}
-
-void
-CcnxProducer::Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
+ NS_ASSERT (GetNode ()->GetObject<CcnxFib> () != 0);
+
+ CcnxApp::StartApplication ();
+
+ GetNode ()->GetObject<CcnxFib> ()->Add (m_prefix, m_face, 0);
+}
+
+void
+CcnxProducer::StopApplication ()
{
NS_LOG_FUNCTION_NOARGS ();
- DataStoreContainer::type::iterator it = m_availableData.get<i_prefix> ().find (header->GetName ());
-
- if (it == m_availableData.end ())
- { // add entry to the top
- m_availableData.get<i_mru> ().push_front (DataStoreEntry (header, packet));
-
- if (m_availableData.size () > m_storeCapacity)
- m_availableData.get<i_mru> ().pop_back ();
- }
- else
- {
- // promote entry to the top
- //m_contentStore.get<i_mru> ().relocate (m_contentStore.get<i_mru> ().begin (),
- // m_contentStore.project<i_mru> (it));
- }
-}*/
+ NS_ASSERT (GetNode ()->GetObject<CcnxFib> () != 0);
+
+ CcnxApp::StopApplication ();
}
+
+
+void
+CcnxProducer::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
+{
+ NS_LOG_FUNCTION (this << interest);
+
+ if (!m_active) return;
+
+ static CcnxContentObjectTail tail;
+ Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
+ header->SetName (Create<CcnxNameComponents> (interest->GetName ()));
+
+ NS_LOG_INFO ("Respodning with ContentObject:\n" << boost::cref(*header));
+
+ Ptr<Packet> packet = Create<Packet> (m_virtualPayloadSize);
+ packet->AddHeader (*header);
+ packet->AddTrailer (tail);
+
+ m_protocolHandler (packet);
+}
+
+} // namespace ns3
diff --git a/apps/ccnx-producer.h b/apps/ccnx-producer.h
index 840400b..ac9a492 100644
--- a/apps/ccnx-producer.h
+++ b/apps/ccnx-producer.h
@@ -16,194 +16,44 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef CCNX_PRODUCER_H
#define CCNX_PRODUCER_H
-#include "ns3/application.h"
-#include "ns3/log.h"
-#include "ns3/random-variable.h"
-#include "ns3/nstime.h"
-#include "ns3/event-id.h"
+#include "ccnx-app.h"
+
#include "ns3/ptr.h"
-#include "ns3/simulator.h"
-#include "ns3/ccnx-interest-header.h"
-#include "ns3/ccnx-local-face.h"
#include "ns3/ccnx-name-components.h"
-#include "ns3/packet.h"
-#include "ns3/boolean.h"
-#include "ns3/integer.h"
-#include "ns3/uinteger.h"
-#include "ns3/random-variable.h"
-#include <limits>
-#include "ns3/pointer.h"
-#include "ns3/traced-callback.h"
-#include "ns3/ccnx-header-helper.h"
-
-#include "ns3/packet.h"
-#include "ns3/header.h"
-#include "ns3/ccnx.h"
-#include "ns3/ccnx-content-object-header.h"
-#include "ns3/ccnx-name-components.h"
-#include "ns3/ccnx-fib.h"
-
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/tag.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/multi_index/hashed_index.hpp>
-#include <boost/multi_index/mem_fun.hpp>
namespace ns3
{
-
- class DataStoreEntry
- {
- public:
- /**
- * \brief Construct data store entry
- *
- * \param header Parsed CcnxContentObject header
- * \param packet Original CCNx packet
- *
- * The constructor will make a copy of the supplied packet and calls
- * RemoveHeader and RemoveTail on the copy.
- */
- DataStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
-
- /**
- * \brief Get prefix of the stored entry
- * \returns prefix of the stored entry
- */
- inline const CcnxNameComponents&
- GetName () const;
-
- /**
- * \brief Get CcnxContentObjectHeader of the stored entry
- * \returns CcnxContentObjectHeader of the stored entry
- */
- inline Ptr<const CcnxContentObjectHeader>
- GetHeader () const;
-
- /**
- * \brief Get content of the stored entry
- * \returns content of the stored entry
- */
- inline Ptr<const Packet>
- GetPacket () const;
-
- /**
- * \brief Convenience method to create a fully formed CCNx packet from stored header and content
- * \returns A read-write copy of the packet with CcnxContentObjectHeader and CcxnContentObjectTail
- */
- Ptr<Packet>
- GetFullyFormedCcnxPacket () const;
-
- // Copy constructor is required by the container. Though, we're
- // storing only two pointers, so shouldn't be a problem
- // private:
- // CcnxContentStoreEntry (const CcnxContentStoreEntry &); ///< disabled copy constructor
- // CcnxContentStoreEntry& operator= (const CcnxContentStoreEntry&); ///< disabled copy operator
-
- private:
- //Ptr<CcnxContentObjectHeader> m_header; ///< \brief non-modifiable CcnxContentObjectHeader
- //Ptr<Packet> m_packet; ///< \brief non-modifiable content of the ContentObject packet
- };
-
-class CcnxProducer: public Application
+class CcnxProducer : public CcnxApp
{
public:
- static TypeId GetTypeId (void);
+ static TypeId
+ GetTypeId (void);
- CcnxProducer ();
-
- virtual ~CcnxProducer ();
-
- //void HandlePacket (const Ptr<CcnxFace> &face, const Ptr<const Packet> &packet);
- //uint32_t GetStoreCapacity();
- //void SetStoreCapacity(uint32_t capacity);
- //void AddContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
-
- void OnInterest(const Ptr<const CcnxInterestHeader> &interest);
-
- CcnxNameComponents GetPrefix() const;
- /**
- * \brief Add a new content to the data store.
- *
- * \param header Fully parsed CcnxContentObjectHeader
- * \param packet Fully formed CCNx packet to add to content store
- * (will be copied and stripped down of headers)
- *
- * If entry with the same prefix exists, the old entry will be
- * promoted to the top of the MRU hash
- */
- //void
- //Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
-
+ CcnxProducer ();
+
+ // inherited from CcnxApp
+ void OnInterest (const Ptr<const CcnxInterestHeader> &interest);
+
protected:
- virtual void DoDispose (void);
+ // inherited from Application base class.
+ virtual void
+ StartApplication (); // Called at time specified by Start
+
+ virtual void
+ StopApplication (); // Called at time specified by Stop
+
private:
- // inherited from Application base class.
- virtual void StartApplication (void); // Called at time specified by Start
- virtual void StopApplication (void); // Called at time specified by Stop
-
- /**
- * \brief Find corresponding CS entry for the given interest
- *
- * \param interest Interest for which matching content store entry
- * will be searched
- *
- * If an entry is found, it is promoted to the top of most recent
- * used entries index, \see m_contentStore
- */
- //Ptr<Packet>
- //Lookup (Ptr<const CcnxInterestHeader> interest);
-
-
- Ptr<Ccnx> m_ccnx;
- Time m_offTime;
-
- //EventId m_sendEvent; // Eventid of pending "send packet" event
- TypeId m_tid;
- Ptr<CcnxLocalFace> m_face;
-
- /*struct DataStoreContainer
- {
- typedef
- boost::multi_index::multi_index_container<
- DataStoreEntry,
- boost::multi_index::indexed_by<
- boost::multi_index::hashed_unique<
- boost::multi_index::tag<__ccnx_private::i_prefix>,
- boost::multi_index::const_mem_fun<DataStoreEntry,
- const CcnxNameComponents&,
- &DataStoreEntry::GetName>,
- CcnxPrefixHash>,
- boost::multi_index::sequenced<boost::multi_index::tag<__ccnx_private::i_mru> >
-#ifdef _DEBUG
- ,
- boost::multi_index::ordered_unique<
- boost::multi_index::tag<__ccnx_private::i_ordered>,
- boost::multi_index::const_mem_fun<DataStoreEntry,
- const CcnxNameComponents&,
- &CcnxContentStoreEntry::GetName>
- >
-#endif
- >
- > type;
- };*/
-
- //helpers
- void CancelEvents ();
-
- //DataStoreContainer::type m_availableData;
- //uint32_t m_storeCapacity;
- uint32_t m_virtualPayloadSize;
- CcnxNameComponents m_prefix;
- TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_interestsTrace;
- TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_contentObjectsTrace;
+ CcnxNameComponents m_prefix;
+ uint32_t m_virtualPayloadSize;
};
+
}
-#endif
+
+#endif // CCNX_PRODUCER_H
diff --git a/examples/annotated-topology-read-example.cc b/examples/annotated-topology-read-example.cc
index 7aff4fe..50c9d13 100644
--- a/examples/annotated-topology-read-example.cc
+++ b/examples/annotated-topology-read-example.cc
@@ -30,7 +30,6 @@
#include "ns3/ipv4-list-routing-helper.h"
#include "ns3/annotated-topology-reader.h"
#include <list>
-#include "ns3/visualizer-module.h"
#include "ns3/ccnx.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/NDNabstraction-module.h"
@@ -42,155 +41,156 @@
int main (int argc, char *argv[])
{
- GlobalValue::Bind ("SimulatorImplementationType", StringValue
- ("ns3::VisualSimulatorImpl"));
- Packet::EnableChecking();
- Packet::EnablePrinting();
- string input ("/Users/iliamo/ns3-abstract-ndn/ns-3.11/src/NDNabstraction/examples/simpletopology.txt");
+ Packet::EnableChecking();
+ Packet::EnablePrinting();
+ string input ("/Users/iliamo/ns3-abstract-ndn/ns-3.11/src/NDNabstraction/examples/simpletopology.txt");
- // Set up command line parameters used to control the experiment.
- //CommandLine cmd;
- //cmd.AddValue ("input", "Name of the input file.",
- // input);
- //cmd.Parse (argc, argv);
+ // Set up command line parameters used to control the experiment.
+ //CommandLine cmd;
+ //cmd.AddValue ("input", "Name of the input file.",
+ // input);
+ //cmd.Parse (argc, argv);
- // ------------------------------------------------------------
- // -- Read topology data.
- // --------------------------------------------
+ // ------------------------------------------------------------
+ // -- Read topology data.
+ // --------------------------------------------
- Ptr<AnnotatedTopologyReader> reader = CreateObject<AnnotatedTopologyReader> ();
- reader->SetFileName (input);
+ Ptr<AnnotatedTopologyReader> reader = CreateObject<AnnotatedTopologyReader> ();
+ reader->SetFileName (input);
- NodeContainer nodes;
- if (reader != 0)
+ NodeContainer nodes;
+ if (reader != 0)
{
- nodes = reader->Read ();
+ nodes = reader->Read ();
}
- if (reader->LinksSize () == 0)
+ if (reader->LinksSize () == 0)
{
- NS_LOG_ERROR ("Problems reading the topology file. Failing.");
- return -1;
+ NS_LOG_ERROR ("Problems reading the topology file. Failing.");
+ return -1;
}
- for(uint32_t j=0; j<nodes.GetN(); j++)
+ for(uint32_t j=0; j<nodes.GetN(); j++)
{
- uint32_t name = j+1;
- std::stringstream ss;
- ss<<name;
- Names::Add (ss.str(), nodes.Get (j));
- NS_LOG_INFO("Name = " << ss.str());
+ uint32_t name = j+1;
+ std::stringstream ss;
+ ss<<name;
+ Names::Add (ss.str(), nodes.Get (j));
+ NS_LOG_INFO("Name = " << ss.str());
}
- // ------------------------------------------------------------
- // -- Create nodes and network stacks
- // --------------------------------------------
- NS_LOG_INFO ("creating internet stack");
- InternetStackHelper stack;
+ // ------------------------------------------------------------
+ // -- Create nodes and network stacks
+ // --------------------------------------------
+ NS_LOG_INFO ("creating internet stack");
+ InternetStackHelper stack;
- //routing
- //Ipv4StaticRoutingHelper staticRouting;
- //Ipv4ListRoutingHelper listRH;
- //listRH.Add (staticRouting, 0);
- //stack.SetRoutingHelper (listRH); // has effect on the next Install ()
- //stack.Install (nodes);
+ //routing
+ //Ipv4StaticRoutingHelper staticRouting;
+ //Ipv4ListRoutingHelper listRH;
+ //listRH.Add (staticRouting, 0);
+ //stack.SetRoutingHelper (listRH); // has effect on the next Install ()
+ //stack.Install (nodes);
- Ipv4GlobalRoutingHelper ipv4RoutingHelper;
- // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
- stack.SetRoutingHelper (ipv4RoutingHelper);
- stack.Install(nodes);
+ Ipv4GlobalRoutingHelper ipv4RoutingHelper;
+ // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
+ stack.SetRoutingHelper (ipv4RoutingHelper);
+ stack.Install(nodes);
- NS_LOG_INFO ("creating ip4 addresses");
- Ipv4AddressHelper address;
- address.SetBase ("10.0.0.0", "255.255.255.252");
+ NS_LOG_INFO ("creating ip4 addresses");
+ Ipv4AddressHelper address;
+ address.SetBase ("10.0.0.0", "255.255.255.252");
- // // Create router nodes, initialize routing database and set up the routing
- // // tables in the nodes.
- Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ // // Create router nodes, initialize routing database and set up the routing
+ // // tables in the nodes.
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
- /*grid.AssignIpv4Addresses (
- Ipv4AddressHelper("10.1.0.0", "255.255.255.0"),
- Ipv4AddressHelper("10.2.0.0", "255.255.255.0")
- );
-*/
+ /*grid.AssignIpv4Addresses (
+ Ipv4AddressHelper("10.1.0.0", "255.255.255.0"),
+ Ipv4AddressHelper("10.2.0.0", "255.255.255.0")
+ );
+ */
- int totlinks = reader->LinksSize ();
+ int totlinks = reader->LinksSize ();
- ///*** applying settings
- NS_LOG_INFO ("creating node containers");
- NodeContainer* nc = new NodeContainer[totlinks];
- TopologyReader::ConstLinksIterator iter;
- int i = 0;
- for ( iter = reader->LinksBegin (); iter != reader->LinksEnd (); iter++, i++ )
+ ///*** applying settings
+ NS_LOG_INFO ("creating node containers");
+ NodeContainer* nc = new NodeContainer[totlinks];
+ TopologyReader::ConstLinksIterator iter;
+ int i = 0;
+ for ( iter = reader->LinksBegin (); iter != reader->LinksEnd (); iter++, i++ )
{
- nc[i] = NodeContainer (iter->GetFromNode (), iter->GetToNode ());
+ nc[i] = NodeContainer (iter->GetFromNode (), iter->GetToNode ());
}
- NetDeviceContainer* ndc = new NetDeviceContainer[totlinks];
- reader->ApplySettings(ndc,nc);
- ///*** settings applied
+ NetDeviceContainer* ndc = new NetDeviceContainer[totlinks];
+ reader->ApplySettings(ndc,nc);
+ ///*** settings applied
- NS_LOG_INFO("installing ccnx stack");
- CcnxStackHelper ccnx(Ccnx::NDN_FLOODING);
- Ptr<CcnxFaceContainer> cf = ccnx.Install (nodes);
+ NS_LOG_INFO("installing ccnx stack");
+ CcnxStackHelper ccnx;
+ ccnx.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
+ ccnx.EnableLimits (false);
+
+ Ptr<CcnxFaceContainer> cf = ccnx.Install (nodes);
- NS_LOG_INFO ("Installing Applications");
- CcnxConsumerHelper helper ("/3");
- ApplicationContainer app = helper.Install (nodes.Get(1));
- app.Start (Seconds (1.0));
- app.Stop (Seconds (1000.05));
+ NS_LOG_INFO ("Installing Applications");
+ CcnxConsumerHelper helper ("/3");
+ ApplicationContainer app = helper.Install (nodes.Get(1));
+ app.Start (Seconds (1.0));
+ app.Stop (Seconds (1000.05));
- /*CcnxConsumerHelper helper2 ("/4");
- ApplicationContainer app2 = helper2.Install(c.Get(5));
- app2.Start (Seconds (1.0));
- app2.Stop (Seconds (1000.05));
- */
- CcnxProducerHelper helper3 ("/3",120);
- ApplicationContainer app3 = helper3.Install(nodes.Get(6));
- app3.Start(Seconds(0.0));
- app3.Stop(Seconds(1500.0));
- /*
- CcnxProducerHelper helper4 ("/4",150);
- ApplicationContainer app4 = helper4.Install(c.Get(0));
- app4.Start(Seconds(0.0));
- app4.Stop(Seconds(1500.0));
- */
+ /*CcnxConsumerHelper helper2 ("/4");
+ ApplicationContainer app2 = helper2.Install(c.Get(5));
+ app2.Start (Seconds (1.0));
+ app2.Stop (Seconds (1000.05));
+ */
+ CcnxProducerHelper helper3 ("/3",120);
+ ApplicationContainer app3 = helper3.Install(nodes.Get(6));
+ app3.Start(Seconds(0.0));
+ app3.Stop(Seconds(1500.0));
+ /*
+ CcnxProducerHelper helper4 ("/4",150);
+ ApplicationContainer app4 = helper4.Install(c.Get(0));
+ app4.Start(Seconds(0.0));
+ app4.Stop(Seconds(1500.0));
+ */
- NS_LOG_INFO("Routes");
- ccnx.AddRoute("1","/3",0,1);
- ccnx.AddRoute("3","/3",1,1);
- ccnx.AddRoute("3","/3",2,2);
- /*ccnx.AddRoute("4","/3",1,1);
+ NS_LOG_INFO("Routes");
+ ccnx.AddRoute("1","/3",0,1);
+ ccnx.AddRoute("3","/3",1,1);
+ ccnx.AddRoute("3","/3",2,2);
+ /*ccnx.AddRoute("4","/3",1,1);
ccnx.AddRoute("5","/3",2,1);
-*/
+ */
- // it creates little subnets, one for each couple of nodes.
- NS_LOG_INFO ("creating ipv4 interfaces");
- Ipv4InterfaceContainer* ipic = new Ipv4InterfaceContainer[totlinks];
- for (int i = 0; i < totlinks; i++)
+ // it creates little subnets, one for each couple of nodes.
+ NS_LOG_INFO ("creating ipv4 interfaces");
+ Ipv4InterfaceContainer* ipic = new Ipv4InterfaceContainer[totlinks];
+ for (int i = 0; i < totlinks; i++)
{
- ipic[i] = address.Assign (ndc[i]);
- address.NewNetwork ();
+ ipic[i] = address.Assign (ndc[i]);
+ address.NewNetwork ();
}
- // ------------------------------------------------------------
- // -- Run the simulation
- // --------------------------------------------
- NS_LOG_INFO ("Run Simulation.");
- Simulator::Stop (Seconds (20));
- Simulator::Run ();
- Simulator::Destroy ();
+ // ------------------------------------------------------------
+ // -- Run the simulation
+ // --------------------------------------------
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Stop (Seconds (20));
+ Simulator::Run ();
+ Simulator::Destroy ();
- delete[] ipic;
- delete[] ndc;
- delete[] nc;
+ delete[] ipic;
+ delete[] ndc;
+ delete[] nc;
- NS_LOG_INFO ("Done.");
+ NS_LOG_INFO ("Done.");
- return 0;
+ return 0;
}
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index 0050805..51d7858 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -24,16 +24,17 @@
#include "ns3/NDNabstraction-module.h"
#include "ns3/point-to-point-grid.h"
#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/netanim-module.h"
#include <iostream>
#include <sstream>
-#include "ns3/visualizer-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("CcnxGrid");
uint32_t nGrid = 3;
+Time finishTime = Seconds (20.0);
void PrintTime ()
{
@@ -42,19 +43,41 @@
Simulator::Schedule (Seconds (10.0), PrintTime);
}
+void PrintFIBs ()
+{
+ NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
+ Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
+ for (NodeList::Iterator node = NodeList::Begin ();
+ node != NodeList::End ();
+ node++)
+ {
+ *routingStream->GetStream () << "Node " << (*node)->GetId () << "\n";
+
+ Ptr<CcnxFib> fib = (*node)->GetObject<CcnxFib> ();
+ NS_ASSERT_MSG (fib != 0, "Fire alarm");
+ *routingStream->GetStream () << *fib << "\n\n";
+ }
+}
+
int
main (int argc, char *argv[])
{
- //GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::VisualSimulatorImpl"));
-
Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
- Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("1ms"));
+ Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("10ms"));
+ Config::SetDefault ("ns3::CcnxConsumer::OffTime", StringValue ("1s"));
+ Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("20"));
Packet::EnableChecking();
Packet::EnablePrinting();
+ std::string animationFile = "";
+ std::string strategy = "ns3::CcnxFloodingStrategy";
+
CommandLine cmd;
cmd.AddValue ("nGrid", "Number of grid nodes", nGrid);
+ cmd.AddValue ("finish", "Finish time", finishTime);
+ cmd.AddValue ("netanim", "NetAnim filename", animationFile);
+ cmd.AddValue ("strategy", "CCNx forwarding strategy", strategy);
cmd.Parse (argc, argv);
PointToPointHelper p2p;
@@ -68,7 +91,9 @@
// Install CCNx stack
NS_LOG_INFO ("Installing CCNx stack");
- CcnxStackHelper ccnxHelper(/*Ccnx::NDN_FLOODING*/Ccnx::NDN_BESTROUTE);
+ CcnxStackHelper ccnxHelper;
+ ccnxHelper.SetForwardingStrategy (strategy);
+ ccnxHelper.EnableLimits (true, Seconds(0.1));
ccnxHelper.InstallAll ();
// Install IP stack (necessary to populate FIB)
@@ -94,39 +119,38 @@
CcnxConsumerHelper consumerHelper (prefix.str ());
ApplicationContainer consumers = consumerHelper.Install (consumerNodes);
- consumers.Start (Seconds (0));
- consumers.Stop (Seconds (2000));
+ // consumers.Start (Seconds (0.0));
+ // consumers.Stop (finishTime);
- CcnxProducerHelper producerHelper (prefix.str (),120);
+ CcnxProducerHelper producerHelper (prefix.str (),1024);
ApplicationContainer producers = producerHelper.Install (producer);
- producers.Start(Seconds(0.0));
- producers.Stop(Seconds(2000.0));
+ // producers.Start(Seconds(0.0));
+ // producers.Stop(finishTime);
- NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
- Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
- for (NodeList::Iterator node = NodeList::Begin ();
- node != NodeList::End ();
- node++)
- {
- *routingStream->GetStream () << "Node " << (*node)->GetId () << "\n";
-
- Ptr<CcnxFib> fib = (*node)->GetObject<CcnxFib> ();
- NS_ASSERT_MSG (fib != 0, "Fire alarm");
- *routingStream->GetStream () << *fib << "\n\n";
- }
+ Simulator::Schedule (Seconds (1.0), PrintFIBs);
Simulator::Schedule (Seconds (10.0), PrintTime);
// 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 (2000));
+ Simulator::Stop (finishTime);
+ AnimationInterface *anim = 0;
+ if (animationFile != "")
+ {
+ anim = new AnimationInterface (animationFile);
+ anim->SetMobilityPollInterval (Seconds (1));
+ }
+
NS_LOG_INFO ("Run Simulation.");
Simulator::Run ();
Simulator::Destroy ();
NS_LOG_INFO ("Done!");
+ if (anim != 0)
+ delete anim;
+
return 0;
}
diff --git a/examples/content-object-example.cc b/examples/content-object-example.cc
index fa9700e..8272e86 100644
--- a/examples/content-object-example.cc
+++ b/examples/content-object-example.cc
@@ -19,38 +19,38 @@
int
main (int argc, char *argv[])
{
- LogComponentEnable ("ContentObjectHeaderExample", LOG_ALL);
- LogComponentEnable ("Packet", LOG_ALL);
+ LogComponentEnable ("ContentObjectHeaderExample", LOG_ALL);
+ LogComponentEnable ("Packet", LOG_ALL);
- NS_LOG_INFO ("Test started");
+ NS_LOG_INFO ("Test started");
- Packet::EnablePrinting ();
- Packet::EnableChecking ();
- Packet packet (10);
+ Packet::EnablePrinting ();
+ Packet::EnableChecking ();
+ Packet packet (10);
- CcnxContentObjectHeader header;
- CcnxContentObjectTail trailer;
+ CcnxContentObjectHeader header;
+ CcnxContentObjectTail trailer;
- Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
- (*testname) ("1");
- header.SetName(testname);
+ Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
+ (*testname) ("1");
+ header.SetName(testname);
- NS_LOG_INFO ("Source: \n" << header << trailer);
+ NS_LOG_INFO ("Source: \n" << header << trailer);
- packet.AddHeader (header);
- packet.AddTrailer (trailer);
+ packet.AddHeader (header);
+ packet.AddTrailer (trailer);
- // NS_LOG_INFO ("Deserialized packet: \n" << packet);
+ // NS_LOG_INFO ("Deserialized packet: \n" << packet);
- NS_LOG_INFO ("Removing and deserializing individual headers");
+ NS_LOG_INFO ("Removing and deserializing individual headers");
- CcnxContentObjectHeader dst_header;
- CcnxContentObjectTail dst_trailer;
+ CcnxContentObjectHeader dst_header;
+ CcnxContentObjectTail dst_trailer;
- packet.RemoveHeader (dst_header);
- packet.RemoveTrailer (dst_trailer);
+ packet.RemoveHeader (dst_header);
+ packet.RemoveTrailer (dst_trailer);
- NS_LOG_INFO ("Target: \n" << dst_header << dst_trailer);
+ NS_LOG_INFO ("Target: \n" << dst_header << dst_trailer);
- return 0;
+ return 0;
}
diff --git a/examples/interest-header-example.cc b/examples/interest-header-example.cc
index a93da9a..6964440 100644
--- a/examples/interest-header-example.cc
+++ b/examples/interest-header-example.cc
@@ -1,3 +1,21 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
#include "ns3/test.h"
#include "ns3/annotated-topology-reader.h"
#include "ns3/ccnx-interest-header.h"
@@ -19,54 +37,53 @@
int
main (int argc, char *argv[])
{
- LogComponentEnable ("InterestHeaderExample", LOG_ALL);
- LogComponentEnable ("Packet", LOG_ALL);
+ // LogComponentEnable ("InterestHeaderExample", LOG_ALL);
+ // LogComponentEnable ("Packet", LOG_ALL);
- NS_LOG_INFO ("Test started");
+ NS_LOG_INFO ("Test started");
- Packet::EnablePrinting ();
- Packet::EnableChecking ();
- Packet packet (0);
+ Packet::EnablePrinting ();
+ Packet::EnableChecking ();
+ Packet packet (0);
- CcnxInterestHeader interestHeader;
+ CcnxInterestHeader interestHeader;
- Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
- (*testname) ("first") ("second");
- interestHeader.SetName(testname);
+ Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
+ (*testname) ("first") ("second");
+ interestHeader.SetName(testname);
- uint32_t minSuffixComponents = 20;
- interestHeader.SetMinSuffixComponents(minSuffixComponents);
+ uint32_t minSuffixComponents = 20;
+ interestHeader.SetMinSuffixComponents(minSuffixComponents);
- uint32_t maxSuffixComponents = 40;
- interestHeader.SetMaxSuffixComponents(maxSuffixComponents);
+ uint32_t maxSuffixComponents = 40;
+ interestHeader.SetMaxSuffixComponents(maxSuffixComponents);
- Time lifetime = Seconds(661777) + MicroSeconds(1234);
- interestHeader.SetInterestLifetime(lifetime);
+ Time lifetime = Seconds(661777) + MicroSeconds(1234);
+ interestHeader.SetInterestLifetime(lifetime);
- bool child = true;
- interestHeader.SetChildSelector(child);
+ bool child = true;
+ interestHeader.SetChildSelector(child);
- Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents> ();
- (*exclude) ("exclude1") ("exclude2");
- interestHeader.SetExclude(exclude);
+ Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents> ();
+ (*exclude) ("exclude1") ("exclude2");
+ interestHeader.SetExclude(exclude);
- UniformVariable random(1, std::numeric_limits<uint32_t>::max ());
- uint32_t randomNonce = static_cast<uint32_t> (random.GetValue());
- interestHeader.SetNonce(randomNonce);
+ UniformVariable random(1, std::numeric_limits<uint32_t>::max ());
+ uint32_t randomNonce = static_cast<uint32_t> (random.GetValue());
+ interestHeader.SetNonce(randomNonce);
- interestHeader.SetNack(true);
- interestHeader.SetCongested(true);
- NS_LOG_INFO ("Source: \n" << interestHeader);
+ interestHeader.SetNack(CcnxInterestHeader::NACK_CONGESTION);
+ NS_LOG_INFO ("Source: \n" << interestHeader);
- packet.AddHeader (interestHeader);
- NS_LOG_INFO ("Deserialized packet: " << packet);
+ packet.AddHeader (interestHeader);
+ NS_LOG_INFO ("Deserialized packet: " << packet);
- NS_LOG_INFO ("Removing and deserializing individual headers");
+ NS_LOG_INFO ("Removing and deserializing individual headers");
- CcnxInterestHeader target;
- packet.RemoveHeader (target);
+ CcnxInterestHeader target;
+ packet.RemoveHeader (target);
- NS_LOG_INFO ("Target: \n" << target);
+ // NS_LOG_INFO ("Target: \n" << target);
- return 0;
+ return 0;
}
diff --git a/examples/packet-sizes.cc b/examples/packet-sizes.cc
new file mode 100644
index 0000000..041cac6
--- /dev/null
+++ b/examples/packet-sizes.cc
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/ccnx-content-object-header.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-header-helper.h"
+#include "ns3/header.h"
+#include "ns3/ccnx-name-components.h"
+#include "ns3/nstime.h"
+#include "ns3/string.h"
+#include "ns3/buffer.h"
+#include "ns3/packet.h"
+#include "ns3/log.h"
+
+using namespace ns3;
+#include <fstream>
+
+NS_LOG_COMPONENT_DEFINE ("PacketSizes");
+
+int
+main (int argc, char *argv[])
+{
+ NS_LOG_INFO ("Test started");
+
+ uint32_t size = 1024;
+ std::string namePrefixStr = "/1";
+ uint32_t start=0, end=100;
+
+ CommandLine cmd;
+ cmd.AddValue ("size", "ContentObject payload size", size);
+ cmd.AddValue ("name", "Prefix", namePrefixStr);
+ cmd.AddValue ("start", "Range start", start);
+ cmd.AddValue ("end", "Range end", end);
+ cmd.Parse (argc, argv);
+
+ CcnxNameComponents namePrefixValue;
+ std::istringstream is (namePrefixStr);
+ is >> namePrefixValue;
+
+ Packet::EnablePrinting ();
+ Packet::EnableChecking ();
+
+ double interestSize = 0.0;
+ double nackSize = 0.0;
+ double contentObjectSize = 0.0;
+
+ double progress = start;
+ double step = (end-start)/100.0;
+
+ progress += step;
+
+ NS_LOG_INFO (progress << ", " << step);
+
+ for (uint32_t currentSize = start; currentSize < end; currentSize++)
+ {
+ Ptr<CcnxNameComponents> namePrefix = Create<CcnxNameComponents> (namePrefixValue);
+ namePrefix->Add (currentSize);
+
+ NS_LOG_LOGIC (boost::cref (*namePrefix));
+
+ // Interest Packet (doesn't have a payload)
+ CcnxInterestHeader interestHeader;
+
+ interestHeader.SetName (namePrefix);
+ interestHeader.SetInterestLifetime (Seconds (4.0));
+ interestHeader.SetNonce (10101010);
+
+ Ptr<Packet> interestPacket = Create<Packet> (0);
+ interestPacket->AddHeader (interestHeader);
+
+ interestSize = interestSize + (1.0*interestPacket->GetSize () - interestSize) / (currentSize - start + 1);
+
+
+
+ // NACK
+ interestHeader.SetNack (CcnxInterestHeader::NACK_GIVEUP_PIT);
+
+ Ptr<Packet> nackPacket = Create<Packet> (0);
+ nackPacket->AddHeader (interestHeader);
+
+ nackSize = nackSize + (1.0*nackPacket->GetSize () - nackSize) / (currentSize - start + 1);
+
+ // ContentObject
+ CcnxContentObjectHeader coHeader;
+ CcnxContentObjectTail coTrailer;
+
+ coHeader.SetName (namePrefix);
+
+ Ptr<Packet> contentObject = Create<Packet> (size);
+
+ contentObject->AddHeader (coHeader);
+ contentObject->AddTrailer (coTrailer);
+
+ contentObjectSize = contentObjectSize + (1.0*contentObject->GetSize () - contentObjectSize ) / (currentSize - start + 1);
+
+ NS_LOG_DEBUG (interestSize << ", " << nackSize << ", " << contentObjectSize);
+
+ if (currentSize >= progress)
+ {
+ NS_LOG_INFO ("Current: " << currentSize << "/" << end);
+ progress += step;
+ }
+ }
+
+ NS_LOG_INFO ("Avg interest: " << interestSize << ", avg nack: " << nackSize << ", avg contentObject: " << contentObjectSize);
+
+ return 0;
+}
diff --git a/examples/syntactic-topology-ndnabstraction.cc b/examples/syntactic-topology-ndnabstraction.cc
index 61f5c49..3fc04a1 100644
--- a/examples/syntactic-topology-ndnabstraction.cc
+++ b/examples/syntactic-topology-ndnabstraction.cc
@@ -28,7 +28,6 @@
#include <iostream>
#include <sstream>
-#include "ns3/visualizer-module.h"
#include "ns3/ccnx.h"
@@ -39,16 +38,13 @@
int
main (int argc, char *argv[])
{
- GlobalValue::Bind ("SimulatorImplementationType", StringValue
- ("ns3::VisualSimulatorImpl"));
-
// Set up some default values for the simulation. Use the
Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
- Packet::EnableChecking();
- Packet::EnablePrinting();
+ Packet::EnableChecking();
+ Packet::EnablePrinting();
// Allow the user to override any of the defaults and the above
// DefaultValue::Bind ()s at run-time, via command-line arguments
@@ -59,13 +55,13 @@
NS_LOG_INFO ("Create nodes.");
NodeContainer c;
c.Create (7);
- Names::Add ("1", c.Get (0));
- Names::Add ("2", c.Get (1));
- Names::Add ("3", c.Get (2));
- Names::Add ("4", c.Get (3));
- Names::Add ("5", c.Get (4));
- Names::Add ("6", c.Get (5));
- Names::Add ("7", c.Get (6));
+ Names::Add ("1", c.Get (0));
+ Names::Add ("2", c.Get (1));
+ Names::Add ("3", c.Get (2));
+ Names::Add ("4", c.Get (3));
+ Names::Add ("5", c.Get (4));
+ Names::Add ("6", c.Get (5));
+ Names::Add ("7", c.Get (6));
NodeContainer n13 = NodeContainer (c.Get (0), c.Get (2));
@@ -108,14 +104,14 @@
p2p.SetChannelAttribute ("Delay", StringValue ("50ms"));
NetDeviceContainer nd35 = p2p.Install (n35);
- InternetStackHelper stack;
- Ipv4GlobalRoutingHelper ipv4RoutingHelper;
- // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
- stack.SetRoutingHelper (ipv4RoutingHelper);
- stack.Install(c);
- // // Create router nodes, initialize routing database and set up the routing
- // // tables in the nodes.
- Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ InternetStackHelper stack;
+ Ipv4GlobalRoutingHelper ipv4RoutingHelper;
+ // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
+ stack.SetRoutingHelper (ipv4RoutingHelper);
+ stack.Install(c);
+ // // Create router nodes, initialize routing database and set up the routing
+ // // tables in the nodes.
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
// Later, we add IP addresses.
NS_LOG_INFO ("Assign IP Addresses.");
@@ -132,38 +128,40 @@
- CcnxStackHelper ccnx(Ccnx::NDN_FLOODING/*Ccnx::NDN_BESTROUTE*/);
- Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
+ CcnxStackHelper ccnx;
+ ccnx.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
+ ccnx.EnableLimits (false);
+ Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
- NS_LOG_INFO ("Installing Applications");
- CcnxConsumerHelper helper ("/3");
- ApplicationContainer app = helper.Install (c.Get(1));
- app.Start (Seconds (1.0));
- app.Stop (Seconds (1000.05));
+ NS_LOG_INFO ("Installing Applications");
+ CcnxConsumerHelper helper ("/3");
+ ApplicationContainer app = helper.Install (c.Get(1));
+ app.Start (Seconds (1.0));
+ app.Stop (Seconds (1000.05));
- /*CcnxConsumerHelper helper2 ("/4");
+ /*CcnxConsumerHelper helper2 ("/4");
ApplicationContainer app2 = helper2.Install(c.Get(5));
app2.Start (Seconds (1.0));
app2.Stop (Seconds (1000.05));
- */
- CcnxProducerHelper helper3 ("/3",120);
- ApplicationContainer app3 = helper3.Install(c.Get(6));
- app3.Start(Seconds(0.0));
- app3.Stop(Seconds(1500.0));
- /*
+ */
+ CcnxProducerHelper helper3 ("/3",120);
+ ApplicationContainer app3 = helper3.Install(c.Get(6));
+ app3.Start(Seconds(0.0));
+ app3.Stop(Seconds(1500.0));
+ /*
CcnxProducerHelper helper4 ("/4",150);
ApplicationContainer app4 = helper4.Install(c.Get(0));
app4.Start(Seconds(0.0));
app4.Stop(Seconds(1500.0));
*/
- ccnx.AddRoute("1","/3",0,1);
- ccnx.AddRoute("3","/3",2,1);
- ccnx.AddRoute("3","/3",3,1);
- ccnx.AddRoute("4","/3",1,1);
- ccnx.AddRoute("5","/3",2,1);
+ ccnx.AddRoute("1","/3",0,1);
+ ccnx.AddRoute("3","/3",2,1);
+ ccnx.AddRoute("3","/3",3,1);
+ ccnx.AddRoute("4","/3",1,1);
+ ccnx.AddRoute("5","/3",2,1);
- /*ccnx.AddRoute ("1", "/3", 0, 1);
+ /*ccnx.AddRoute ("1", "/3", 0, 1);
ccnx.AddRoute ("1", "/3", 1, 1);
ccnx.AddRoute ("2", "/3", 1, 1);
@@ -182,40 +180,40 @@
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s from n0 to n4
/*NS_LOG_INFO ("Create Applications.");
- uint16_t port = 9; // Discard port (RFC 863)
+ uint16_t port = 9; // Discard port (RFC 863)
- std::string sendsizeattr = "SendSize";
- //flow2 7-->2
- BulkSendHelper bulksend0 ("ns3::UdpSocketFactory", InetSocketAddress (i23.GetAddress (0), port));
- //bulksend0.SetAttribute(sendsizeattr, AttributeValue(ConstantVariable(2560)));
- bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
- ApplicationContainer apps = bulksend0.Install(c.Get(6));
- apps.Start(Seconds (1.0));
- apps.Stop(Seconds (10.0));
+ std::string sendsizeattr = "SendSize";
+ //flow2 7-->2
+ BulkSendHelper bulksend0 ("ns3::UdpSocketFactory", InetSocketAddress (i23.GetAddress (0), port));
+ //bulksend0.SetAttribute(sendsizeattr, AttributeValue(ConstantVariable(2560)));
+ bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
+ ApplicationContainer apps = bulksend0.Install(c.Get(6));
+ apps.Start(Seconds (1.0));
+ apps.Stop(Seconds (10.0));
- // Create a packet sink to receive these packets
- PacketSinkHelper sink0 ("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny (), port));
- apps = sink0.Install(c.Get(1));
- apps.Start(Seconds(0.0));
- apps.Stop(Seconds(20.0));
+ // Create a packet sink to receive these packets
+ PacketSinkHelper sink0 ("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny (), port));
+ apps = sink0.Install(c.Get(1));
+ apps.Start(Seconds(0.0));
+ apps.Stop(Seconds(20.0));
- //flow1 1-->6
- BulkSendHelper bulksend ("ns3::UdpSocketFactory", InetSocketAddress (i56.GetAddress (1), port));
- //bulksend.SetAttribute(sendsizeattr, AttributeValue( ConstantVariable(2560)));
- bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
- apps = bulksend.Install (c.Get (0));
- apps.Start (Seconds (6.0));
- apps.Stop (Seconds (20.0));
+ //flow1 1-->6
+ BulkSendHelper bulksend ("ns3::UdpSocketFactory", InetSocketAddress (i56.GetAddress (1), port));
+ //bulksend.SetAttribute(sendsizeattr, AttributeValue( ConstantVariable(2560)));
+ bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
+ apps = bulksend.Install (c.Get (0));
+ apps.Start (Seconds (6.0));
+ apps.Stop (Seconds (20.0));
- // Create a packet sink to receive these packets
- PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
- apps = sink.Install (c.Get (5));
- apps.Start(Seconds(0.0));
- apps.Stop(Seconds(20.0));
+ // Create a packet sink to receive these packets
+ PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
+ apps = sink.Install (c.Get (5));
+ apps.Start(Seconds(0.0));
+ apps.Stop(Seconds(20.0));
- AsciiTraceHelper ascii;
- p2p.EnableAsciiAll (ascii.CreateFileStream ("sync-topology-ndnabstraction.tr"));
- p2p.EnablePcapAll ("sync-topology-ndnabstraction");*/
+ AsciiTraceHelper ascii;
+ p2p.EnableAsciiAll (ascii.CreateFileStream ("sync-topology-ndnabstraction.tr"));
+ p2p.EnablePcapAll ("sync-topology-ndnabstraction");*/
Simulator::Stop (Seconds (2000));
@@ -224,5 +222,5 @@
Simulator::Destroy ();
NS_LOG_INFO ("Done.");
- return 0;
+ return 0;
}
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/syntax-tree/ccnb-parser-base-tag.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-base-tag.h
index 6b7fe76..15310a5 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-base-tag.h
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-base-tag.h
@@ -39,7 +39,7 @@
public:
std::list<Ptr<Block> > m_attrs; ///< \brief List of attributes, associated with this tag
std::list<Ptr<Block> > m_nestedTags; ///< \brief List of nested tags
-
+
protected:
/**
* \brief Default constructor
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
index d0f795f..29e3fac 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
@@ -28,6 +28,10 @@
#include "ccnb-parser-dattr.h"
#include "ccnb-parser-ext.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("CcnbParserBlock");
+
namespace ns3 {
namespace CcnbParser {
@@ -57,7 +61,7 @@
value <<= 4;
value += ( (byte&(~CCN_TT_HBIT)) >> 3);
-
+
/**
* Huh. After fighting with NS-3, it became apparent that Create<T>(...) construct
* doesn't work with references. Just simply doesn't work. wtf?
@@ -65,23 +69,27 @@
switch (byte & CCN_TT_MASK)
{
case CCN_BLOB:
- return Ptr<Blob> (new Blob(start, value));
+ return Ptr<Blob> (new Blob(start, value), false);
case CCN_UDATA:
- return Ptr<Udata> (new Udata(start, value));
+ return Ptr<Udata> (new Udata(start, value), false);
case CCN_TAG:
- return Ptr<Tag> (new Tag(start, value));
+ return Ptr<Tag> (new Tag(start, value), false);
case CCN_ATTR:
- return Ptr<Attr> (new Attr(start, value));
+ return Ptr<Attr> (new Attr(start, value), false);
case CCN_DTAG:
- return Ptr<Dtag> (new Dtag(start, value));
+ return Ptr<Dtag> (new Dtag(start, value), false);
case CCN_DATTR:
- return Ptr<Dattr> (new Dattr(start, value));
+ return Ptr<Dattr> (new Dattr(start, value), false);
case CCN_EXT:
- return Ptr<Ext> (new Ext(start, value));
+ return Ptr<Ext> (new Ext(start, value), false);
default:
throw CcnbDecodingException ();
}
}
+Block::~Block ()
+{
+}
+
}
}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.h
index 59ccf02..a188597 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.h
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.h
@@ -56,6 +56,8 @@
*/
static Ptr<Block>
ParseBlock (Buffer::Iterator &start);
+
+ virtual ~Block ();
virtual void accept( VoidNoArguVisitor &v ) = 0;
virtual void accept( VoidVisitor &v, boost::any param ) = 0;
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
index 992fae5..c436923 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
@@ -34,6 +34,10 @@
#include <boost/foreach.hpp>
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("CcnbParserInterestVisitor");
+
namespace ns3 {
namespace CcnbParser {
@@ -50,10 +54,12 @@
static NonceVisitor nonceVisitor;
CcnxInterestHeader &interest = *(boost::any_cast<CcnxInterestHeader*> (param));
-
+
switch (n.m_dtag)
{
case CCN_DTAG_Interest:
+ NS_LOG_DEBUG ("Interest");
+
// process nested blocks
BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
{
@@ -62,6 +68,8 @@
break;
case CCN_DTAG_Name:
{
+ NS_LOG_DEBUG ("Name");
+
// process name components
Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
@@ -73,6 +81,7 @@
break;
}
case CCN_DTAG_MinSuffixComponents:
+ NS_LOG_DEBUG ("MinSuffixComponents");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
interest.SetMinSuffixComponents (
@@ -82,6 +91,7 @@
)));
break;
case CCN_DTAG_MaxSuffixComponents:
+ NS_LOG_DEBUG ("MaxSuffixComponents");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
interest.SetMaxSuffixComponents (
@@ -92,6 +102,7 @@
break;
case CCN_DTAG_Exclude:
{
+ NS_LOG_DEBUG ("Exclude");
// process exclude components
Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents> ();
@@ -103,6 +114,7 @@
break;
}
case CCN_DTAG_ChildSelector:
+ NS_LOG_DEBUG ("ChildSelector");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
@@ -113,6 +125,7 @@
)));
break;
case CCN_DTAG_AnswerOriginKind:
+ NS_LOG_DEBUG ("AnswerOriginKind");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
interest.SetAnswerOriginKind (
@@ -122,6 +135,7 @@
)));
break;
case CCN_DTAG_Scope:
+ NS_LOG_DEBUG ("Scope");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
interest.SetScope (
@@ -131,16 +145,18 @@
)));
break;
case CCN_DTAG_InterestLifetime:
+ NS_LOG_DEBUG ("InterestLifetime");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
interest.SetInterestLifetime (
boost::any_cast<Time> (
- (*n.m_nestedTags.begin())->accept(
- timestampVisitor
- )));
+ (*n.m_nestedTags.begin())->accept(
+ timestampVisitor
+ )));
break;
case CCN_DTAG_Nonce:
+ NS_LOG_DEBUG ("Nonce");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbDecodingException ();
@@ -152,22 +168,14 @@
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)));
- break;
-
- case NDN_DTAG_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)));
+ boost::any_cast<uint32_t> (
+ (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
break;
}
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-no-argu-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-visitor.h
index 6f6bcc2..ce3e712 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-no-argu-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-visitor.h
@@ -44,6 +44,8 @@
virtual boost::any visit (Dtag& )=0; ///< \brief Method accepting DTAG block
virtual boost::any visit (Dattr&)=0; ///< \brief Method accepting DATTR block
virtual boost::any visit (Ext& )=0; ///< \brief Method accepting EXT block
+
+ virtual ~NoArguVisitor () { }
};
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
index 22965aa..ea4ab00 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
@@ -44,7 +44,6 @@
}
uint8_t combo = start[n.m_blobSize-2]; // 4 most significant bits hold 4 least significant bits of number of seconds
seconds = (seconds << 4) | (combo >> 4);
- std::cout << std::hex << (int) start[n.m_blobSize-2] << "\n";
nanoseconds = combo & 0x0F; /*00001111*/ // 4 least significant bits hold 4 most significant bits of number of
nanoseconds = (nanoseconds << 8) | start[n.m_blobSize-1];
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-visitor.h
index 24212d4..e0fac3a 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-visitor.h
@@ -44,6 +44,8 @@
virtual boost::any visit (Dtag&, boost::any)=0; ///< \brief Method accepting DTAG block
virtual boost::any visit (Dattr&, boost::any)=0; ///< \brief Method accepting DATTR block
virtual boost::any visit (Ext&, boost::any)=0; ///< \brief Method accepting EXT block
+
+ virtual ~Visitor () { }
};
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-visitor.h
index 975c0c6..ad0ff74 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-visitor.h
@@ -43,6 +43,8 @@
virtual void visit (Dtag& )=0; ///< \brief Method accepting DTAG block
virtual void visit (Dattr&)=0; ///< \brief Method accepting DATTR block
virtual void visit (Ext& )=0; ///< \brief Method accepting EXT block
+
+ virtual ~VoidNoArguVisitor () { }
};
}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-void-visitor.h
index 9b45836..4fd228d 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-void-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-visitor.h
@@ -44,6 +44,8 @@
virtual void visit (Dtag&, boost::any)=0; ///< \brief Method accepting DTAG block
virtual void visit (Dattr&, boost::any)=0; ///< \brief Method accepting DATTR block
virtual void visit (Ext&, boost::any)=0; ///< \brief Method accepting EXT block
+
+ virtual ~VoidVisitor () { }
};
}
diff --git a/helper/ccnx-decoding-helper.cc b/helper/ccnx-decoding-helper.cc
index 52061ab..408190b 100644
--- a/helper/ccnx-decoding-helper.cc
+++ b/helper/ccnx-decoding-helper.cc
@@ -29,6 +29,10 @@
#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("CcnxDecodingHelper");
+
namespace ns3 {
size_t
@@ -39,7 +43,7 @@
Buffer::Iterator i = start;
Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
root->accept (interestVisitor, &interest);
-
+
return i.GetDistanceFrom (start);
}
diff --git a/helper/ccnx-encoding-helper.cc b/helper/ccnx-encoding-helper.cc
index 20ea101..15757fc 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>
@@ -162,16 +156,10 @@
{
written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
}
- if (interest.IsNack () )
+ if (interest.GetNack ()>0)
{
- written += EstimateBlockHeader (CcnbParser::NDN_DTAG_Nack);
- written += EstimateNumber (1);
- written += 1;
- }
- if (interest.IsCongested () )
- {
- written += EstimateBlockHeader (CcnbParser::NDN_DTAG_Congested);
- written += EstimateNumber (1);
+ written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Nack);
+ written += EstimateNumber (interest.GetNack ());
written += 1;
}
diff --git a/helper/ccnx-forwarding-helper.cc b/helper/ccnx-forwarding-helper.cc
index 6a8d3fb..0e74e97 100644
--- a/helper/ccnx-forwarding-helper.cc
+++ b/helper/ccnx-forwarding-helper.cc
@@ -26,43 +26,11 @@
#include "ccnx-forwarding-helper.h"
namespace ns3 {
-
-CcnxForwardingHelper::CcnxForwardingHelper()
-{
- m_strategy = Ccnx::NDN_FLOODING;
-}
-CcnxForwardingHelper::CcnxForwardingHelper(Ccnx::ForwardingStrategy strategy)
+CcnxForwardingHelper::CcnxForwardingHelper ()
{
- m_strategy = strategy;
}
-CcnxForwardingHelper::~CcnxForwardingHelper ()
-{
-
-}
-
-void
-CcnxForwardingHelper::SetForwarding(Ptr<Ccnx> ccnx, Ptr<CcnxPit> pit) const
-{
- if(m_strategy == Ccnx::NDN_FLOODING)
- {
- Ptr<CcnxFloodingStrategy> ccnxForwarding = CreateObject<CcnxFloodingStrategy> ();
- //ccnxForwarding->SetCcnx(ccnx);
- ccnxForwarding->SetPit(pit);
- ccnx->SetForwardingStrategy (ccnxForwarding);
- }
- else if(m_strategy == Ccnx::NDN_BESTROUTE)
- {
- Ptr<CcnxBestRouteStrategy> ccnxForwarding = CreateObject<CcnxBestRouteStrategy> ();
- //ccnxForwarding->SetCcnx(ccnx);
- ccnxForwarding->SetPit(pit);
- ccnx->SetForwardingStrategy (ccnxForwarding);
- }
- else if (m_strategy == Ccnx::NDN_RANKING)
- {}
-}
-
// void
// CcnxForwardingHelper::PrintForwardingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const
// {
diff --git a/helper/ccnx-forwarding-helper.h b/helper/ccnx-forwarding-helper.h
index fe9f9d4..5a59381 100644
--- a/helper/ccnx-forwarding-helper.h
+++ b/helper/ccnx-forwarding-helper.h
@@ -42,77 +42,60 @@
class CcnxForwardingHelper
{
public:
-
/*
- * \brief Default constructor, which sets NDN_FLOODING forwarding strategy
+ * \brief Default constructor
*/
CcnxForwardingHelper();
-
- /*
- * \brief This constructor sets a specified forwarding strategy
- */
- CcnxForwardingHelper(Ccnx::ForwardingStrategy strategy);
-
- /*
- * Destroy an instance of an CcnxForwardingHelper
- */
- ~CcnxForwardingHelper ();
-
- /*
- * \brief creates a specified ForwardingStrategy object and binds it to Pit
- */
- void SetForwarding(Ptr<Ccnx> ccnx, Ptr<CcnxPit> pit) const;
- /**
- * \brief prints the forwarding tables of all nodes at a particular time.
- * \param printTime the time at which the forwarding table is supposed to be printed.
- * \param stream The output stream object to use
- *
- * This method calls the PrintForwardingTable() method of the
- * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
- * specified time; the output format is forwarding protocol-specific.
- */
- void PrintForwardingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const;
+ // /**
+ // * \brief prints the forwarding tables of all nodes at a particular time.
+ // * \param printTime the time at which the forwarding table is supposed to be printed.
+ // * \param stream The output stream object to use
+ // *
+ // * This method calls the PrintForwardingTable() method of the
+ // * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
+ // * specified time; the output format is forwarding protocol-specific.
+ // */
+ // void PrintForwardingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const;
- /**
- * \brief prints the forwarding tables of all nodes at regular intervals specified by user.
- * \param printInterval the time interval for which the forwarding table is supposed to be printed.
- * \param stream The output stream object to use
- *
- * This method calls the PrintForwardingTable() method of the
- * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
- * specified time interval; the output format is forwarding protocol-specific.
- */
- void PrintForwardingTableAllEvery (Time printInterval, Ptr<OutputStreamWrapper> stream) const;
+ // /**
+ // * \brief prints the forwarding tables of all nodes at regular intervals specified by user.
+ // * \param printInterval the time interval for which the forwarding table is supposed to be printed.
+ // * \param stream The output stream object to use
+ // *
+ // * This method calls the PrintForwardingTable() method of the
+ // * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
+ // * specified time interval; the output format is forwarding protocol-specific.
+ // */
+ // void PrintForwardingTableAllEvery (Time printInterval, Ptr<OutputStreamWrapper> stream) const;
- /**
- * \brief prints the forwarding tables of a node at a particular time.
- * \param printTime the time at which the forwarding table is supposed to be printed.
- * \param node The node ptr for which we need the forwarding table to be printed
- * \param stream The output stream object to use
- *
- * This method calls the PrintForwardingTable() method of the
- * CcnxForwardingStrategy stored in the Ccnx object, for the selected node
- * at the specified time; the output format is forwarding protocol-specific.
- */
- void PrintForwardingTableAt (Time printTime, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+ // /**
+ // * \brief prints the forwarding tables of a node at a particular time.
+ // * \param printTime the time at which the forwarding table is supposed to be printed.
+ // * \param node The node ptr for which we need the forwarding table to be printed
+ // * \param stream The output stream object to use
+ // *
+ // * This method calls the PrintForwardingTable() method of the
+ // * CcnxForwardingStrategy stored in the Ccnx object, for the selected node
+ // * at the specified time; the output format is forwarding protocol-specific.
+ // */
+ // void PrintForwardingTableAt (Time printTime, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
- /**
- * \brief prints the forwarding tables of a node at regular intervals specified by user.
- * \param printInterval the time interval for which the forwarding table is supposed to be printed.
- * \param node The node ptr for which we need the forwarding table to be printed
- * \param stream The output stream object to use
- *
- * This method calls the PrintForwardingTable() method of the
- * CcnxForwardingStrategy stored in the Ccnx object, for the selected node
- * at the specified interval; the output format is forwarding protocol-specific.
- */
- void PrintForwardingTableEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+ // /**
+ // * \brief prints the forwarding tables of a node at regular intervals specified by user.
+ // * \param printInterval the time interval for which the forwarding table is supposed to be printed.
+ // * \param node The node ptr for which we need the forwarding table to be printed
+ // * \param stream The output stream object to use
+ // *
+ // * This method calls the PrintForwardingTable() method of the
+ // * CcnxForwardingStrategy stored in the Ccnx object, for the selected node
+ // * at the specified interval; the output format is forwarding protocol-specific.
+ // */
+ // void PrintForwardingTableEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
private:
- Ccnx::ForwardingStrategy m_strategy;
- void Print (Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
- void PrintEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+ // void Print (Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+ // void PrintEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
};
} // namespace ns3
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index f8f0405..d9f9d6b 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -71,11 +71,14 @@
#include "ns3/ccnx-l3-protocol.h"
#include "ns3/ccnx-fib.h"
#include "ns3/node-list.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-helper.h"
-#include "ns3/ipv4-global-routing-ordered-nexthops.h"
+#include "ns3/loopback-net-device.h"
#include "ns3/global-router-interface.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-global-routing.h"
+#include "ns3/ipv4-global-routing-ordered-nexthops.h"
+#include "ns3/ipv4-routing-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/data-rate.h"
#include "ccnx-face-container.h"
#include "ccnx-stack-helper.h"
@@ -85,6 +88,8 @@
#include <map>
#include <boost/foreach.hpp>
+#define NDN_DEFAULT_DATA_SIZE 1024
+
NS_LOG_COMPONENT_DEFINE ("CcnxStackHelper");
namespace ns3 {
@@ -112,47 +117,37 @@
// leaks. Global maps of protocol/face pairs to file objects seems to
// fit the bill.
//
-typedef std::pair<Ptr<Ccnx>, uint32_t> FacePairCcnx;
-typedef std::map<FacePairCcnx, Ptr<PcapFileWrapper> > FaceFileMapCcnx;
-typedef std::map<FacePairCcnx, Ptr<OutputStreamWrapper> > FaceStreamMapCcnx;
+// typedef std::pair<Ptr<Ccnx>, uint32_t> FacePairCcnx;
+// typedef std::map<FacePairCcnx, Ptr<PcapFileWrapper> > FaceFileMapCcnx;
+// typedef std::map<FacePairCcnx, Ptr<OutputStreamWrapper> > FaceStreamMapCcnx;
-static FaceFileMapCcnx g_faceFileMapCcnx; /**< A mapping of Ccnx/face pairs to pcap files */
-static FaceStreamMapCcnx g_faceStreamMapCcnx; /**< A mapping of Ccnx/face pairs to ascii streams */
+// static FaceFileMapCcnx g_faceFileMapCcnx; /**< A mapping of Ccnx/face pairs to pcap files */
+// static FaceStreamMapCcnx g_faceStreamMapCcnx; /**< A mapping of Ccnx/face pairs to ascii streams */
CcnxStackHelper::CcnxStackHelper ()
- : m_forwardingHelper (Ccnx::NDN_FLOODING)
{
-}
-
-CcnxStackHelper::CcnxStackHelper (Ccnx::ForwardingStrategy strategy)
- : m_forwardingHelper (strategy)
-{
+ m_strategyFactory.SetTypeId ("ns3::CcnxFloodingStrategy");
}
CcnxStackHelper::~CcnxStackHelper ()
{
}
-CcnxStackHelper::CcnxStackHelper (const CcnxStackHelper &o)
-{
-}
-
-CcnxStackHelper &
-CcnxStackHelper::operator = (const CcnxStackHelper &o)
-{
- if (this == &o)
- {
- return *this;
- }
- return *this;
-}
-
void
-CcnxStackHelper::SetForwardingStrategy (Ccnx::ForwardingStrategy strategy)
+CcnxStackHelper::SetForwardingStrategy (std::string strategy)
{
- CcnxForwardingHelper newForwardingHelper (strategy);
- m_forwardingHelper = newForwardingHelper;
+ m_strategyFactory.SetTypeId (strategy);
+}
+
+void
+CcnxStackHelper::EnableLimits (bool enable/* = true*/, Time avgRtt/*=Seconds(0.1)*/, uint32_t avgContentObject/*=1100*/, uint32_t avgInterest/*=40*/)
+{
+ NS_LOG_INFO ("EnableLimits: " << enable);
+ m_limitsEnabled = enable;
+ m_avgContentObjectSize = avgContentObject;
+ m_avgInterestSize = avgInterest;
+ m_avgRtt = avgRtt;
}
Ptr<CcnxFaceContainer>
@@ -172,15 +167,6 @@
return Install (NodeContainer::GetGlobal ());
}
-// void
-// CcnxStackHelper::CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId)
-// {
-// ObjectFactory factory;
-// factory.SetTypeId (typeId);
-// Ptr<Object> protocol = factory.Create <Object> ();
-// node->AggregateObject (protocol);
-// }
-
Ptr<CcnxFaceContainer>
CcnxStackHelper::Install (Ptr<Node> node) const
{
@@ -200,42 +186,50 @@
Ptr<CcnxL3Protocol> ccnx = CreateObject<CcnxL3Protocol> ();
node->AggregateObject (ccnx);
- Ptr<CcnxPit> pit = ccnx->GetPit();
- NS_LOG_INFO("NODE->GetNDevices()="<<node->GetNDevices());
-
+ ccnx->SetForwardingStrategy
+ (DynamicCast<CcnxForwardingStrategy> (m_strategyFactory.Create<Object> ()));
+
for (uint32_t index=0; index < node->GetNDevices (); index++)
{
- Ptr<PointToPointNetDevice> device = DynamicCast<PointToPointNetDevice>(node->GetDevice(index));
- if(device == 0)
- continue;
-
- Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node->GetDevice (index));
- face->SetNode (node);
+ Ptr<NetDevice> device = node->GetDevice (index);
+ if (DynamicCast<LoopbackNetDevice> (device) != 0)
+ continue; // don't create face for a LoopbackNetDevice
+
+ Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node, device);
+
uint32_t __attribute__ ((unused)) face_id = ccnx->AddFace (face);
NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << face_id);
- // Setup bucket filtering
- // Assume that we know average data packet size, and this size is equal default size
- // Set maximum buckets (averaging over 1 second)
+
+ if (m_limitsEnabled)
+ {
+ NS_LOG_INFO ("Limits are enabled");
+ Ptr<PointToPointNetDevice> p2p = DynamicCast<PointToPointNetDevice> (device);
+ if (p2p == 0)
+ {
+ NS_LOG_INFO ("Non p2p interface");
+ continue; // only PointToPointNetDevice supports limits
+ }
+
+ // Setup bucket filtering
+ // Assume that we know average data packet size, and this size is equal default size
+ // Set maximum buckets (averaging over 1 second)
- DataRateValue dataRate;
- device->GetAttribute ("DataRate", dataRate);
- NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
- pit->maxBucketsPerFace[face->GetId()] = 0.1 * dataRate.Get().GetBitRate () /(NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
- NS_LOG_INFO("maxBucketsPerFace["<<face->GetId()<<"] = " << pit->maxBucketsPerFace[face->GetId()]);
- pit->leakSize[face->GetId()] = 0.97 * NDN_INTEREST_RESET_PERIOD / SECOND * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
- NS_LOG_INFO("pit->leakSize["<<face->GetId()<<"] = " << pit->leakSize[face->GetId()]);
+ DataRateValue dataRate; device->GetAttribute ("DataRate", dataRate);
+
+ NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
+
+ double maxInterestPackets = 1.0 * dataRate.Get ().GetBitRate () / 8.0 / m_avgContentObjectSize;
+ NS_LOG_INFO ("BucketMax: " << maxInterestPackets);
+
+ // Set bucket max to BDP
+ face->SetBucketMax (m_avgRtt.ToDouble (Time::S) * maxInterestPackets); // number of interests allowed
+ face->SetBucketLeak (maxInterestPackets);
+ }
-
- if(face->IsLocal()==true)
- NS_LOG_INFO("Face #" << face_id << " is turned on");
face->SetUp ();
faces->Add (face);
}
- m_forwardingHelper.SetForwarding (ccnx, pit);
-
- ccnx->ScheduleLeakage ();
-
return faces;
}
@@ -274,10 +268,10 @@
AddRoute (node, prefix, face, metric);
}
/*
-void
-CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
-{
- NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
+ void
+ CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
+ {
+ NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
NS_ASSERT_MSG (node != 0, "Node does not exist");
@@ -289,259 +283,259 @@
CcnxNameComponentsValue prefixValue;
prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
fib->Add (prefixValue.Get (), face, metric);
-}
+ }
*/
-static void
-CcnxL3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ccnx> ccnx, uint32_t face)
-{
- NS_LOG_FUNCTION (p << ccnx << face);
+// static void
+// CcnxL3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ccnx> ccnx, uint32_t face)
+// {
+// NS_LOG_FUNCTION (p << ccnx << face);
- //
- // Since trace sources are independent of face, if we hook a source
- // on a particular protocol we will get traces for all of its faces.
- // We need to filter this to only report faces for which the user
- // has expressed interest.
- //
- FacePairCcnx pair = std::make_pair (ccnx, face);
- if (g_faceFileMapCcnx.find (pair) == g_faceFileMapCcnx.end ())
- {
- NS_LOG_INFO ("Ignoring packet to/from face " << face);
- return;
- }
+// //
+// // Since trace sources are independent of face, if we hook a source
+// // on a particular protocol we will get traces for all of its faces.
+// // We need to filter this to only report faces for which the user
+// // has expressed interest.
+// //
+// FacePairCcnx pair = std::make_pair (ccnx, face);
+// if (g_faceFileMapCcnx.find (pair) == g_faceFileMapCcnx.end ())
+// {
+// NS_LOG_INFO ("Ignoring packet to/from face " << face);
+// return;
+// }
- Ptr<PcapFileWrapper> file = g_faceFileMapCcnx[pair];
- file->Write (Simulator::Now (), p);
-}
+// Ptr<PcapFileWrapper> file = g_faceFileMapCcnx[pair];
+// file->Write (Simulator::Now (), p);
+// }
-bool
-CcnxStackHelper::PcapHooked (Ptr<Ccnx> ccnx)
-{
- for (FaceFileMapCcnx::const_iterator i = g_faceFileMapCcnx.begin ();
- i != g_faceFileMapCcnx.end ();
- ++i)
- {
- if ((*i).first.first == ccnx)
- {
- return true;
- }
- }
- return false;
-}
+// bool
+// CcnxStackHelper::PcapHooked (Ptr<Ccnx> ccnx)
+// {
+// for (FaceFileMapCcnx::const_iterator i = g_faceFileMapCcnx.begin ();
+// i != g_faceFileMapCcnx.end ();
+// ++i)
+// {
+// if ((*i).first.first == ccnx)
+// {
+// return true;
+// }
+// }
+// return false;
+// }
-void
-CcnxStackHelper::EnablePcapCcnxInternal (std::string prefix, Ptr<Ccnx> ccnx, uint32_t face, bool explicitFilename)
-{
- NS_LOG_FUNCTION (prefix << ccnx << face);
+// void
+// CcnxStackHelper::EnablePcapCcnxInternal (std::string prefix, Ptr<Ccnx> ccnx, uint32_t face, bool explicitFilename)
+// {
+// NS_LOG_FUNCTION (prefix << ccnx << face);
- //
- // We have to create a file and a mapping from protocol/face to file
- // irrespective of how many times we want to trace a particular protocol.
- //
- PcapHelper pcapHelper;
+// //
+// // We have to create a file and a mapping from protocol/face to file
+// // irrespective of how many times we want to trace a particular protocol.
+// //
+// PcapHelper pcapHelper;
- std::string filename;
- if (explicitFilename)
- {
- filename = prefix;
- }
- else
- {
- filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
- }
+// std::string filename;
+// if (explicitFilename)
+// {
+// filename = prefix;
+// }
+// else
+// {
+// filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
+// }
- Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
+// Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
- //
- // However, we only hook the trace source once to avoid multiple trace sink
- // calls per event (connect is independent of face).
- //
- if (!PcapHooked (ccnx))
- {
- //
- // Ptr<Ccnx> is aggregated to node and CcnxL3Protocol is aggregated to
- // node so we can get to CcnxL3Protocol through Ccnx.
- //
- Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
- NS_ASSERT_MSG (ccnxL3Protocol, "CcnxStackHelper::EnablePcapCcnxInternal(): "
- "m_ccnxEnabled and ccnxL3Protocol inconsistent");
+// //
+// // However, we only hook the trace source once to avoid multiple trace sink
+// // calls per event (connect is independent of face).
+// //
+// if (!PcapHooked (ccnx))
+// {
+// //
+// // Ptr<Ccnx> is aggregated to node and CcnxL3Protocol is aggregated to
+// // node so we can get to CcnxL3Protocol through Ccnx.
+// //
+// Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
+// NS_ASSERT_MSG (ccnxL3Protocol, "CcnxStackHelper::EnablePcapCcnxInternal(): "
+// "m_ccnxEnabled and ccnxL3Protocol inconsistent");
- bool result = ccnxL3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&CcnxL3ProtocolRxTxSink));
- NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal(): "
- "Unable to connect ccnxL3Protocol \"Tx\"");
+// bool result = ccnxL3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&CcnxL3ProtocolRxTxSink));
+// NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal(): "
+// "Unable to connect ccnxL3Protocol \"Tx\"");
- result = ccnxL3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&CcnxL3ProtocolRxTxSink));
- NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal(): "
- "Unable to connect ccnxL3Protocol \"Rx\"");
- // cast result to void, to suppress ‘result’ set but not used compiler-warning
- // for optimized builds
- (void) result;
- }
+// result = ccnxL3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&CcnxL3ProtocolRxTxSink));
+// NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal(): "
+// "Unable to connect ccnxL3Protocol \"Rx\"");
+// // cast result to void, to suppress ‘result’ set but not used compiler-warning
+// // for optimized builds
+// (void) result;
+// }
- g_faceFileMapCcnx[std::make_pair (ccnx, face)] = file;
-}
+// g_faceFileMapCcnx[std::make_pair (ccnx, face)] = file;
+// }
-static void
-CcnxL3ProtocolDropSinkWithoutContext (
- Ptr<OutputStreamWrapper> stream,
- Ptr<const Packet> packet,
- CcnxL3Protocol::DropReason reason,
- Ptr<Ccnx> ccnx,
- uint32_t face)
-{
- //
- // Since trace sources are independent of face, if we hook a source
- // on a particular protocol we will get traces for all of its faces.
- // We need to filter this to only report faces for which the user
- // has expressed interest.
- //
- FacePairCcnx pair = std::make_pair (ccnx, face);
- if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
- {
- NS_LOG_INFO ("Ignoring packet to/from face " << face);
- return;
- }
+// static void
+// CcnxL3ProtocolDropSinkWithoutContext (
+// Ptr<OutputStreamWrapper> stream,
+// Ptr<const Packet> packet,
+// CcnxL3Protocol::DropReason reason,
+// Ptr<Ccnx> ccnx,
+// uint32_t face)
+// {
+// //
+// // Since trace sources are independent of face, if we hook a source
+// // on a particular protocol we will get traces for all of its faces.
+// // We need to filter this to only report faces for which the user
+// // has expressed interest.
+// //
+// FacePairCcnx pair = std::make_pair (ccnx, face);
+// if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
+// {
+// NS_LOG_INFO ("Ignoring packet to/from face " << face);
+// return;
+// }
- *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
-}
+// *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+// }
-static void
-CcnxL3ProtocolDropSinkWithContext (
- Ptr<OutputStreamWrapper> stream,
- std::string context,
- Ptr<const Packet> packet,
- CcnxL3Protocol::DropReason reason,
- Ptr<Ccnx> ccnx,
- uint32_t face)
-{
- //
- // Since trace sources are independent of face, if we hook a source
- // on a particular protocol we will get traces for all of its faces.
- // We need to filter this to only report faces for which the user
- // has expressed interest.
- //
- FacePairCcnx pair = std::make_pair (ccnx, face);
- if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
- {
- NS_LOG_INFO ("Ignoring packet to/from face " << face);
- return;
- }
+// static void
+// CcnxL3ProtocolDropSinkWithContext (
+// Ptr<OutputStreamWrapper> stream,
+// std::string context,
+// Ptr<const Packet> packet,
+// CcnxL3Protocol::DropReason reason,
+// Ptr<Ccnx> ccnx,
+// uint32_t face)
+// {
+// //
+// // Since trace sources are independent of face, if we hook a source
+// // on a particular protocol we will get traces for all of its faces.
+// // We need to filter this to only report faces for which the user
+// // has expressed interest.
+// //
+// FacePairCcnx pair = std::make_pair (ccnx, face);
+// if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
+// {
+// NS_LOG_INFO ("Ignoring packet to/from face " << face);
+// return;
+// }
- *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << face << ") "
- << *packet << std::endl;
-}
+// *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << face << ") "
+// << *packet << std::endl;
+// }
-bool
-CcnxStackHelper::AsciiHooked (Ptr<Ccnx> ccnx)
-{
- for ( FaceStreamMapCcnx::const_iterator i = g_faceStreamMapCcnx.begin ();
- i != g_faceStreamMapCcnx.end ();
- ++i)
- {
- if ((*i).first.first == ccnx)
- {
- return true;
- }
- }
- return false;
-}
+// bool
+// CcnxStackHelper::AsciiHooked (Ptr<Ccnx> ccnx)
+// {
+// for ( FaceStreamMapCcnx::const_iterator i = g_faceStreamMapCcnx.begin ();
+// i != g_faceStreamMapCcnx.end ();
+// ++i)
+// {
+// if ((*i).first.first == ccnx)
+// {
+// return true;
+// }
+// }
+// return false;
+// }
-void
-CcnxStackHelper::EnableAsciiCcnxInternal (
- Ptr<OutputStreamWrapper> stream,
- std::string prefix,
- Ptr<Ccnx> ccnx,
- uint32_t face,
- bool explicitFilename)
-{
- //
- // Our trace sinks are going to use packet printing, so we have to
- // make sure that is turned on.
- //
- Packet::EnablePrinting ();
+// void
+// CcnxStackHelper::EnableAsciiCcnxInternal (
+// Ptr<OutputStreamWrapper> stream,
+// std::string prefix,
+// Ptr<Ccnx> ccnx,
+// uint32_t face,
+// bool explicitFilename)
+// {
+// //
+// // Our trace sinks are going to use packet printing, so we have to
+// // make sure that is turned on.
+// //
+// Packet::EnablePrinting ();
- //
- // If we are not provided an OutputStreamWrapper, we are expected to create
- // one using the usual trace filename conventions and hook WithoutContext
- // since there will be one file per context and therefore the context would
- // be redundant.
- //
- if (stream == 0)
- {
- //
- // Set up an output stream object to deal with private ofstream copy
- // constructor and lifetime issues. Let the helper decide the actual
- // name of the file given the prefix.
- //
- // We have to create a stream and a mapping from protocol/face to
- // stream irrespective of how many times we want to trace a particular
- // protocol.
- //
- AsciiTraceHelper asciiTraceHelper;
+// //
+// // If we are not provided an OutputStreamWrapper, we are expected to create
+// // one using the usual trace filename conventions and hook WithoutContext
+// // since there will be one file per context and therefore the context would
+// // be redundant.
+// //
+// if (stream == 0)
+// {
+// //
+// // Set up an output stream object to deal with private ofstream copy
+// // constructor and lifetime issues. Let the helper decide the actual
+// // name of the file given the prefix.
+// //
+// // We have to create a stream and a mapping from protocol/face to
+// // stream irrespective of how many times we want to trace a particular
+// // protocol.
+// //
+// AsciiTraceHelper asciiTraceHelper;
- std::string filename;
- if (explicitFilename)
- {
- filename = prefix;
- }
- else
- {
- filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
- }
+// std::string filename;
+// if (explicitFilename)
+// {
+// filename = prefix;
+// }
+// else
+// {
+// filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
+// }
- Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
+// Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
- //
- // However, we only hook the trace sources once to avoid multiple trace sink
- // calls per event (connect is independent of face).
- //
- if (!AsciiHooked (ccnx))
- {
- //
- // The drop sink for the CcnxL3Protocol uses a different signature than
- // the default sink, so we have to cook one up for ourselves. We can get
- // to the Ptr<CcnxL3Protocol> through our Ptr<Ccnx> since they must both
- // be aggregated to the same node.
- //
- Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
- bool __attribute__ ((unused)) result = ccnxL3Protocol->TraceConnectWithoutContext ("Drop",
- MakeBoundCallback (&CcnxL3ProtocolDropSinkWithoutContext, theStream));
- NS_ASSERT_MSG (result == true, "CcnxStackHelper::EanableAsciiCcnxInternal(): "
- "Unable to connect ccnxL3Protocol \"Drop\"");
- }
+// //
+// // However, we only hook the trace sources once to avoid multiple trace sink
+// // calls per event (connect is independent of face).
+// //
+// if (!AsciiHooked (ccnx))
+// {
+// //
+// // The drop sink for the CcnxL3Protocol uses a different signature than
+// // the default sink, so we have to cook one up for ourselves. We can get
+// // to the Ptr<CcnxL3Protocol> through our Ptr<Ccnx> since they must both
+// // be aggregated to the same node.
+// //
+// Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
+// bool __attribute__ ((unused)) result = ccnxL3Protocol->TraceConnectWithoutContext ("Drop",
+// MakeBoundCallback (&CcnxL3ProtocolDropSinkWithoutContext, theStream));
+// NS_ASSERT_MSG (result == true, "CcnxStackHelper::EanableAsciiCcnxInternal(): "
+// "Unable to connect ccnxL3Protocol \"Drop\"");
+// }
- g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = theStream;
- return;
- }
+// g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = theStream;
+// return;
+// }
- //
- // If we are provided an OutputStreamWrapper, we are expected to use it, and
- // to provide a context. We are free to come up with our own context if we
- // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
- // compatibility and simplicity, we just use Config::Connect and let it deal
- // with the context.
- //
- // We need to associate the ccnx/face with a stream to express interest
- // in tracing events on that pair, however, we only hook the trace sources
- // once to avoid multiple trace sink calls per event (connect is independent
- // of face).
- //
- if (!AsciiHooked (ccnx))
- {
- Ptr<Node> node = ccnx->GetObject<Node> ();
- std::ostringstream oss;
+// //
+// // If we are provided an OutputStreamWrapper, we are expected to use it, and
+// // to provide a context. We are free to come up with our own context if we
+// // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
+// // compatibility and simplicity, we just use Config::Connect and let it deal
+// // with the context.
+// //
+// // We need to associate the ccnx/face with a stream to express interest
+// // in tracing events on that pair, however, we only hook the trace sources
+// // once to avoid multiple trace sink calls per event (connect is independent
+// // of face).
+// //
+// if (!AsciiHooked (ccnx))
+// {
+// Ptr<Node> node = ccnx->GetObject<Node> ();
+// std::ostringstream oss;
- //
- // This has all kinds of parameters coming with, so we have to cook up our
- // own sink.
- //
- oss.str ("");
- oss << "/NodeList/" << node->GetId () << "/$ns3::CcnxL3Protocol/Drop";
- Config::Connect (oss.str (), MakeBoundCallback (&CcnxL3ProtocolDropSinkWithContext, stream));
- }
+// //
+// // This has all kinds of parameters coming with, so we have to cook up our
+// // own sink.
+// //
+// oss.str ("");
+// oss << "/NodeList/" << node->GetId () << "/$ns3::CcnxL3Protocol/Drop";
+// Config::Connect (oss.str (), MakeBoundCallback (&CcnxL3ProtocolDropSinkWithContext, stream));
+// }
- g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = stream;
-}
+// g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = stream;
+// }
void
CcnxStackHelper::InstallFakeGlobalRoutes ()
@@ -556,7 +550,7 @@
NS_ASSERT_MSG (Ipv4RoutingHelper::GetRouting<Ipv4GlobalRoutingOrderedNexthops>
(
(*node)->GetObject<Ipv4> ()->GetRoutingProtocol ()
- ),
+ ),
"InternetStack should have Ipv4GlobalRoutingOrderedNexthops as routing protocol");
// Example:
//
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index 1a76201..ee166fc 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -29,8 +29,8 @@
#include "ccnx-trace-helper.h"
#include "ns3/ccnx-forwarding-helper.h"
#include "ns3/ccnx.h"
-#include "ns3/data-rate.h"
#include "ns3/ccnx-interest-header.h"
+#include "ns3/nstime.h"
namespace ns3 {
@@ -58,7 +58,7 @@
* attribute or a set of functionality that may be of interest to many other
* classes.
*/
-class CcnxStackHelper : public PcapHelperForCcnx, public AsciiTraceHelperForCcnx
+class CcnxStackHelper //: public PcapHelperForCcnx, public AsciiTraceHelperForCcnx
{
public:
/**
@@ -67,19 +67,12 @@
CcnxStackHelper();
/**
- * \brief Create a new CcnxStackHelper with a specified forwarding strategy
- */
- CcnxStackHelper (Ccnx::ForwardingStrategy);
-
- /**
* \brief Destroy the CcnxStackHelper
*/
virtual ~CcnxStackHelper ();
- CcnxStackHelper (const CcnxStackHelper &);
- CcnxStackHelper &operator = (const CcnxStackHelper &o);
/**
- * Set forwarding strategy helper
+ * @brief Set forwarding strategy helper
*
* \param forwarding a new forwarding helper
*
@@ -89,9 +82,20 @@
* a single ns3::Ccnx object through its ns3::Ccnx::SetforwardingProtocol.
*/
void
- SetForwardingStrategy (Ccnx::ForwardingStrategy strategy);
+ SetForwardingStrategy (std::string forwardingStrategy);
/**
+ * @brief Enable Interest limits (disabled by default)
+ *
+ * @param enable Enable or disable limits
+ * @param avgRtt Average RTT
+ * @param avgContentObject Average size of contentObject packets (including all headers)
+ * @param avgInterest Average size of interest packets (including all headers)
+ */
+ void
+ EnableLimits (bool enable = true, Time avgRtt=Seconds(0.1), uint32_t avgContentObject=1100, uint32_t avgInterest=40);
+
+ /**
* \brief Install CCNx stack on the node
*
* This method will assert if called on a node that already has Ccnx object
@@ -192,58 +196,66 @@
*/
void
InstallRoutesToAll ();
+
+private:
+ CcnxStackHelper (const CcnxStackHelper &);
+ CcnxStackHelper &operator = (const CcnxStackHelper &o);
private:
- CcnxForwardingHelper m_forwardingHelper;
-
- /**
- * @brief Enable pcap output the indicated Ccnx and interface pair.
- * @internal
- *
- * @param prefix Filename prefix to use for pcap files.
- * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
- * @param interface Interface ID on the Ccnx on which you want to enable tracing.
- */
- virtual void EnablePcapCcnxInternal (std::string prefix,
- Ptr<Ccnx> ccnx,
- uint32_t interface,
- bool explicitFilename);
+ ObjectFactory m_strategyFactory;
+ bool m_limitsEnabled;
+ Time m_avgRtt;
+ uint32_t m_avgContentObjectSize;
+ uint32_t m_avgInterestSize;
+
+ // /**
+ // * @brief Enable pcap output the indicated Ccnx and interface pair.
+ // * @internal
+ // *
+ // * @param prefix Filename prefix to use for pcap files.
+ // * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
+ // * @param interface Interface ID on the Ccnx on which you want to enable tracing.
+ // */
+ // virtual void EnablePcapCcnxInternal (std::string prefix,
+ // Ptr<Ccnx> ccnx,
+ // uint32_t interface,
+ // bool explicitFilename);
- /**
- * @brief Enable ascii trace output on the indicated Ccnx and interface pair.
- * @internal
- *
- * @param stream An OutputStreamWrapper representing an existing file to use
- * when writing trace data.
- * @param prefix Filename prefix to use for ascii trace files.
- * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
- * @param interface Interface ID on the Ccnx on which you want to enable tracing.
- */
- virtual void EnableAsciiCcnxInternal (Ptr<OutputStreamWrapper> stream,
- std::string prefix,
- Ptr<Ccnx> ccnx,
- uint32_t interface,
- bool explicitFilename);
+ // /**
+ // * @brief Enable ascii trace output on the indicated Ccnx and interface pair.
+ // * @internal
+ // *
+ // * @param stream An OutputStreamWrapper representing an existing file to use
+ // * when writing trace data.
+ // * @param prefix Filename prefix to use for ascii trace files.
+ // * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
+ // * @param interface Interface ID on the Ccnx on which you want to enable tracing.
+ // */
+ // virtual void EnableAsciiCcnxInternal (Ptr<OutputStreamWrapper> stream,
+ // std::string prefix,
+ // Ptr<Ccnx> ccnx,
+ // uint32_t interface,
+ // bool explicitFilename);
+
+ // // /**
+ // // * \internal
+ // // */
+ // // static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
// /**
// * \internal
// */
- // static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
+ // static void Cleanup (void);
- /**
- * \internal
- */
- static void Cleanup (void);
+ // /**
+ // * \internal
+ // */
+ // bool PcapHooked (Ptr<Ccnx> ccnx);
- /**
- * \internal
- */
- bool PcapHooked (Ptr<Ccnx> ccnx);
-
- /**
- * \internal
- */
- bool AsciiHooked (Ptr<Ccnx> ccnx);
+ // /**
+ // * \internal
+ // */
+ // bool AsciiHooked (Ptr<Ccnx> ccnx);
};
} // namespace ns3
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index 625b6d7..b850d08 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -19,30 +19,31 @@
*/
#include "ccnx-bestroute-strategy.h"
+#include "ccnx-interest-header.h"
+
#include "ns3/assert.h"
+#include "ns3/log.h"
-#include "ccnx-route.h"
-
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
NS_LOG_COMPONENT_DEFINE ("CcnxBestRouteStrategy");
-namespace __ccnx_private {
-
- struct CcnxFibFaceMetricByFace;
-}
namespace ns3
{
-
+
using namespace __ccnx_private;
-
+
NS_OBJECT_ENSURE_REGISTERED (CcnxBestRouteStrategy);
TypeId CcnxBestRouteStrategy::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CcnxBestRouteStrategy")
- .SetGroupName ("Ccnx")
- .SetParent<Object> ()
- ;
+ .SetGroupName ("Ccnx")
+ .SetParent <CcnxForwardingStrategy> ()
+ .AddConstructor <CcnxBestRouteStrategy> ()
+ ;
return tid;
}
@@ -50,50 +51,58 @@
{
}
-
bool
-CcnxBestRouteStrategy::PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry,
- CcnxFibEntryContainer::type::iterator fibEntry,
+CcnxBestRouteStrategy::PropagateInterest (const CcnxPitEntry &pitEntry,
const Ptr<CcnxFace> &incomingFace,
Ptr<CcnxInterestHeader> &header,
- const Ptr<const Packet> &packet,
- SendCallback ucb)
+ const Ptr<const Packet> &packet)
{
- //NS_LOG_FUNCTION(this);
- //NS_LOG_INFO(*fibEntry);
-
- Ptr<CcnxFace> bestFace = fibEntry->FindBestCandidate(0);
-
- if( bestFace == NULL )
+ NS_LOG_FUNCTION (this);
+
+ // Try to work out with just green faces
+ bool greenOk = PropagateInterestViaGreen (pitEntry, incomingFace, header, packet);
+ if (greenOk)
+ return true;
+
+ int propagatedCount = 0;
+
+ BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry.m_faces.get<i_metric> ())
{
- return false;
+ if (metricFace.m_status == CcnxFibFaceMetric::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.m_incoming.find (metricFace.m_face) != pitEntry.m_incoming.end ())
+ continue; // don't forward to face that we received interest from
+
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
+ pitEntry.m_outgoing.find (metricFace.m_face);
+
+ if (outgoing != pitEntry.m_outgoing.end () &&
+ outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
+ {
+ continue; // already forwarded before during this retransmission cycle
+ }
+
+ bool faceAvailable = metricFace.m_face->IsBelowLimit ();
+ if (!faceAvailable) // huh...
+ {
+ continue;
+ }
+
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
+
+ metricFace.m_face->Send (packet->Copy ());
+
+ propagatedCount++;
+ break; // do only once
}
- else
- {
- bool tryResult = GetPit ()->TryAddOutgoing (pitEntry, bestFace);
- if (tryResult == false)
- {
- NS_LOG_INFO("!!!!!!!!!!!!!Trying different face!!!!!!!!!!!!!!!!");
- for(uint32_t i = 1; i<fibEntry->m_faces.size(); i++ )
- {
- bestFace = fibEntry->FindBestCandidate(i);
- tryResult = GetPit ()->TryAddOutgoing (pitEntry, bestFace);
- if(tryResult == true)
- break;
- NS_LOG_INFO("Trying different face");
- }
-
- if(tryResult == false)
- {
- NS_LOG_INFO("FAILURE");
- return false;
- }
- }
-
- ucb (bestFace, header, packet->Copy());
- }
-
- return true;
+
+ NS_LOG_INFO ("Propagated to " << propagatedCount << " faces");
+ return propagatedCount > 0;
}
} //namespace ns3
diff --git a/model/ccnx-bestroute-strategy.h b/model/ccnx-bestroute-strategy.h
index 8abaae9..f2d591b 100644
--- a/model/ccnx-bestroute-strategy.h
+++ b/model/ccnx-bestroute-strategy.h
@@ -22,14 +22,7 @@
#ifndef CCNX_BESTROUTE_STRATEGY_H
#define CCNX_BESTROUTE_STRATEGY_H
-#include "ns3/packet.h"
-#include "ns3/callback.h"
-#include "ns3/object.h"
-#include "ns3/log.h"
-
#include "ccnx-forwarding-strategy.h"
-#include "ccnx.h"
-#include "ccnx-fib.h"
namespace ns3
{
@@ -40,21 +33,25 @@
/**
* \ingroup ccnx
* \brief Best route strategy
+ *
+ * \todo Describe
*/
-
class CcnxBestRouteStrategy : public CcnxForwardingStrategy
{
public:
- static TypeId GetTypeId (void);
+ static TypeId GetTypeId (void);
+
+ /**
+ * @brief Default constructor
+ */
+ CcnxBestRouteStrategy ();
- CcnxBestRouteStrategy ();
-
- bool PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry,
- CcnxFibEntryContainer::type::iterator fibEntry,
- const Ptr<CcnxFace> &incomingFace,
- Ptr<CcnxInterestHeader> &header,
- const Ptr<const Packet> &packet,
- SendCallback ucb);
+ // inherited from CcnxForwardingStrategy
+ virtual bool
+ PropagateInterest (const CcnxPitEntry &pitEntry,
+ const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &packet);
};
} //namespace ns3
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index 110e7ac..4875386 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -150,7 +150,7 @@
}
-Ptr<Packet>
+boost::tuple<Ptr<Packet>, Ptr<const 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..dd0f884 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<const CcnxContentObjectHeader> >
Lookup (Ptr<const CcnxInterestHeader> interest);
/**
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index 7821055..40ac57b 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -21,38 +21,34 @@
#include "ccnx-face.h"
+#include "ns3/packet.h"
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/assert.h"
+#include <boost/ref.hpp>
+
NS_LOG_COMPONENT_DEFINE ("CcnxFace");
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
* invoke SetUp on them once an Ccnx address and mask have been set.
*/
-CcnxFace::CcnxFace ()
- // : m_metric (1)
- : m_node (0)
+CcnxFace::CcnxFace (Ptr<Node> node)
+ : m_node (node)
+ , m_bucket (0.0)
+ , m_bucketMax (-1.0)
+ , m_bucketLeak (0.0)
+ , m_protocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ())
, m_ifup (false)
, m_id ((uint32_t)-1)
{
NS_LOG_FUNCTION (this);
+
+ NS_ASSERT_MSG (node != 0, "node cannot be NULL. Check the code");
}
CcnxFace::~CcnxFace ()
@@ -69,19 +65,94 @@
return *this;
}
-
-// void
-// CcnxFace::DoDispose (void)
-// {
-// NS_LOG_FUNCTION_NOARGS ();
-// m_node = 0;
-// Object::DoDispose ();
-// }
-
-void
-CcnxFace::SetNode (Ptr<Node> node)
+void
+CcnxFace::RegisterProtocolHandler (ProtocolHandler handler)
{
- m_node = node;
+ NS_LOG_FUNCTION_NOARGS ();
+
+ m_protocolHandler = handler;
+}
+
+bool
+CcnxFace::IsBelowLimit ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ /// \todo Implement tracing, if requested
+ if (!IsUp ())
+ return false;
+
+ if (m_bucketMax > 0)
+ {
+ //NS_LOG_DEBUG ("Limits enabled: " << m_bucketMax << ", current: " << m_bucket);
+ if (m_bucket+1.0 > m_bucketMax)
+ {
+ //NS_LOG_DEBUG ("Returning false");
+ return false;
+ }
+
+ m_bucket += 1.0;
+ }
+
+ return true;
+}
+
+void
+CcnxFace::LeakBucket (const Time &interval)
+{
+ const double leak = m_bucketLeak * interval.ToDouble (Time::S);
+ m_bucket = std::max (0.0, m_bucket - leak);
+
+ // NS_LOG_DEBUG ("max: " << m_bucketMax << ", Current bucket: " << m_bucket << ", leak size: " << leak << ", interval: " << interval << ", " << m_bucketLeak);
+}
+
+void
+CcnxFace::SetBucketMax (double bucket)
+{
+ NS_LOG_FUNCTION (this << bucket);
+ m_bucketMax = bucket;
+}
+
+void
+CcnxFace::SetBucketLeak (double leak)
+{
+ NS_LOG_FUNCTION (this << leak);
+ m_bucketLeak = leak;
+}
+
+void
+CcnxFace::LeakBucketByOnePacket ()
+{
+ m_bucket = std::max (0.0, m_bucket-1.0);
+}
+
+bool
+CcnxFace::Send (Ptr<Packet> packet)
+{
+ NS_LOG_FUNCTION (boost::cref (*this) << packet << packet->GetSize ());
+
+ /// \todo Implement tracing, if requested
+
+ if (!IsUp ())
+ return false;
+
+ SendImpl (packet);
+ return true;
+}
+
+bool
+CcnxFace::Receive (const Ptr<const Packet> &packet)
+{
+ NS_LOG_FUNCTION (boost::cref (*this) << packet << packet->GetSize ());
+
+ /// \todo Implement tracing, if requested
+
+ if (!IsUp ())
+ return false;
+
+ m_protocolHandler (this, packet);
+
+ return true;
}
// void
@@ -110,37 +181,18 @@
return m_ifup;
}
-bool
-CcnxFace::IsDown (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return !m_ifup;
-}
-
void
-CcnxFace::SetUp (void)
+CcnxFace::SetUp (bool up/* = true*/)
{
NS_LOG_FUNCTION_NOARGS ();
- m_ifup = true;
-}
-
-void
-CcnxFace::SetDown (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_ifup = false;
-}
-
-bool
-CcnxFace::IsLocal() const
-{
- return m_isLocal;
+ m_ifup = up;
}
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 +200,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..0499abb 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -22,16 +22,16 @@
#define CCNX_FACE_H
#include <ostream>
+#include <algorithm>
#include "ns3/ptr.h"
-#include "ns3/simple-ref-count.h"
-#include "ns3/callback.h"
+#include "ns3/ccnx.h"
+#include "ns3/nstime.h"
namespace ns3 {
class Packet;
class Node;
-
/**
* \ingroup ccnx
@@ -54,21 +54,14 @@
* \brief Ccnx protocol hanler
*
* \param face Face from which packet has been received
- * \param packet Received packet
+ * \param packet Original 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
*/
- CcnxFace ();
+ CcnxFace (Ptr<Node> node);
virtual ~CcnxFace();
////////////////////////////////////////////////////////////////////
@@ -78,23 +71,39 @@
*
* This method should call protocol-dependent registration function
*/
- virtual void RegisterProtocolHandler (ProtocolHandler handler) = 0;
+ virtual void
+ RegisterProtocolHandler (ProtocolHandler handler);
+
+ /**
+ * @brief Check if Interest limit is reached
+ *
+ * Side effect: if limit is not yet reached, the number of outstanding packets will be increased
+ *
+ * @returns true if Interest limit is not yet reached
+ */
+ bool
+ IsBelowLimit ();
/**
* \brief Send packet on a face
*
+ * This method will be called by lower layers to send data to device or application
+ *
* \param p smart pointer to a packet to send
+ *
+ * @return false if either limit is reached
*/
- virtual void Send (Ptr<Packet> p) = 0;
-
- ////////////////////////////////////////////////////////////////////
+ bool
+ Send (Ptr<Packet> p);
/**
- * \brief Associate Node object with face
+ * \brief Receive packet from application or another node and forward it to the CCNx stack
*
- * \param node smart pointer to a Node object
+ * \todo The only reason for this call is to handle tracing, if requested
*/
- virtual void SetNode (Ptr<Node> node);
+ bool
+ Receive (const Ptr<const Packet> &p);
+ ////////////////////////////////////////////////////////////////////
// /**
// * \Brief Assign routing/forwarding metric with face
@@ -117,29 +126,16 @@
*/
/**
- * \brief Enable this face
+ * \brief Enable or disable this face
*/
- virtual void SetUp ();
-
- /**
- * \brief Disable this face
- */
- virtual void SetDown (void);
+ virtual void
+ SetUp (bool up = true);
/**
* \brief Returns true if this face is enabled, false otherwise.
*/
- virtual bool IsUp () const;
-
- /**
- * \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 bool
+ IsUp () const;
virtual std::ostream&
Print (std::ostream &os) const;
@@ -165,6 +161,31 @@
GetId () const;
/**
+ * @brief Set maximum value for Interest allowance
+ *
+ * @param bucket maximum value for Interest allowance. If < 0, then limit will be disabled
+ */
+ void
+ SetBucketMax (double bucket);
+
+ /**
+ * @brief Set a normalized value (one second) for Interest allowance bucket leak
+ */
+ void
+ SetBucketLeak (double leak);
+
+ /**
+ * @brief Leak the Interest allowance bucket by (1/interval) * m_bucketMax amount
+ *
+ * @param interval Time interval with which the bucket is leaked
+ */
+ void
+ LeakBucket (const Time &interval);
+
+ void
+ LeakBucketByOnePacket ();
+
+ /**
* \brief Compare two faces. Only two faces on the same node could be compared.
*
* Internal index is used for comparison.
@@ -179,9 +200,15 @@
*/
bool
operator< (const CcnxFace &face) const;
-
-// protected:
-// virtual void DoDispose (void);
+
+protected:
+ /**
+ * \brief Send packet on a face (actual implementation)
+ *
+ * \param p smart pointer to a packet to send
+ */
+ virtual void
+ SendImpl (Ptr<Packet> p) = 0;
private:
CcnxFace (const CcnxFace &); ///< \brief Disabled copy constructor
@@ -190,12 +217,15 @@
protected:
// 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)
+
+ double m_bucket; ///< \brief Value representing current size of the Interest allowance for this face
+ double m_bucketMax; ///< \brief Maximum Interest allowance for this face
+ double m_bucketLeak; ///< \brief Normalized amount that should be leaked every second
+private:
+ ProtocolHandler m_protocolHandler; ///< Callback via which packets are getting send to CCNx stack
+ 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)
};
std::ostream& operator<< (std::ostream& os, const CcnxFace &face);
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index f8c5956..0df2ded 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -33,10 +33,10 @@
#define NDN_RTO_BETA 0.25
#define NDN_RTO_K 4
-//#define NDN_DEBUG_OSPF 0
-//#define NDN_DEBUG_OSPF_NODES 0
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
-//#define NDN_DUMP_FIB 0
namespace ns3 {
@@ -51,48 +51,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,74 +70,88 @@
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::UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample)
{
- 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,
+ ll::bind (&CcnxFibFaceMetric::UpdateRtt, ll::_1, sample));
// 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)
+CcnxFibEntry::UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status)
{
- NS_LOG_FUNCTION(this);
- NS_ASSERT_MSG (m_face != NULL, "Trying to Add or Update NULL face");
+ NS_LOG_FUNCTION (this << boost::cref(*face) << status);
- CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
- if (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");
+
+ m_faces.modify (record,
+ (&ll::_1)->*&CcnxFibFaceMetric::m_status = status);
+
+ // reordering random access index same way as by metric index
+ m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
+}
+
+void
+CcnxFibEntry::AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
+{
+ NS_LOG_FUNCTION (this);
+ NS_ASSERT_MSG (face != NULL, "Trying to Add or Update NULL face");
+
+ CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
+ if (record == m_faces.get<i_face> ().end ())
{
- entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
+ m_faces.insert (CcnxFibFaceMetric (face, metric));
}
else
{
- entry.m_faces.modify (record, ChangeMetric (m_metric));
- }
+ m_faces.modify (record,
+ (&ll::_1)->*&CcnxFibFaceMetric::m_routingCost = 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 ());
+ m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
}
-void
-CcnxFibEntry::UpdateFaceRtt::operator() (CcnxFibEntry &entry)
+const CcnxFibFaceMetric &
+CcnxFibEntry::FindBestCandidate (uint32_t skip/* = 0*/) const
{
- 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
-{
+ if (m_faces.size () == 0) throw CcnxFibEntry::NoFaces ();
skip = skip % m_faces.size();
- return m_faces.get<i_nth> () [skip].GetFace ();
+ return m_faces.get<i_nth> () [skip];
}
@@ -198,7 +170,9 @@
void
CcnxFib::DoDispose (void)
{
+ clear ();
m_node = 0;
+ clear ();
Object::DoDispose ();
}
@@ -234,11 +208,37 @@
}
NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
- modify (entry, CcnxFibEntry::AddOrUpdateRoutingMetric (face, metric));
+ modify (entry,
+ ll::bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, ll::_1, face, metric));
return entry;
}
+void
+CcnxFib::Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face)
+{
+ NS_LOG_FUNCTION (this);
+
+ modify (iterator_to (entry),
+ ll::bind (&CcnxFibEntry::RemoveFace, ll::_1, face));
+ if (entry.m_faces.size () == 0)
+ {
+ erase (iterator_to (entry));
+ }
+}
+
+void
+CcnxFib::RemoveFromAll (Ptr<CcnxFace> face)
+{
+ NS_LOG_FUNCTION (this);
+
+ for_each (begin (), end (), ll::bind (&CcnxFib::Remove, this, ll::_1, face));
+ // BOOST_FOREACH (const CcnxFibEntry &entry, *this)
+ // {
+ // Remove (entry, face);
+ // }
+}
+
std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
{
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index afb86a3..3e7807b 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)
@@ -155,6 +150,8 @@
class CcnxFibEntry : public SimpleRefCount<CcnxFibEntry>
{
public:
+ class NoFaces {};
+
/**
* \brief Constructor
* \param prefix Prefix for the FIB entry
@@ -165,47 +162,24 @@
{ }
/**
- * \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 (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status);
/**
- * \brief Unary function to add or update routing metric of FIB next hop
+ * \brief 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;
- };
+ void AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric);
/**
- * \brief Unary function to recalculate smoothed RTT and RTT variation
- * \param rttSample RTT sample
+ * @brief Update RTT averages for the face
*/
- 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;
- };
-
+ void
+ UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample);
+
/**
* \brief Get prefix for the FIB entry
*/
@@ -214,9 +188,20 @@
/**
* \brief Find "best route" candidate, skipping `skip' first candidates (modulo # of faces)
+ *
+ * throws CcnxFibEntry::NoFaces if m_faces.size()==0
*/
- Ptr<CcnxFace>
- FindBestCandidate (int skip = 0) const;
+ const CcnxFibFaceMetric &
+ FindBestCandidate (uint32_t skip = 0) const;
+
+ /**
+ * @brief Remove record associated with `face`
+ */
+ void
+ RemoveFace (const Ptr<CcnxFace> &face)
+ {
+ m_faces.erase (face);
+ }
private:
friend std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
@@ -276,15 +261,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,23 +285,20 @@
*/
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 );
+ /**
+ * @brief Remove reference to a face from the entry. If entry had only this face, the whole
+ * entry will be removed
+ */
+ void
+ Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face);
- // // 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
+ /**
+ * @brief Remove all references to a face from FIB. If for some enty that face was the only element,
+ * this FIB entry will be removed.
+ */
+ void
+ RemoveFromAll (Ptr<CcnxFace> face);
protected:
// inherited from Object class
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 83ddd7e..4a8dd50 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -20,128 +20,106 @@
#include "ccnx-flooding-strategy.h"
#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ccnx-interest-header.h"
-#include "ccnx-route.h"
+#include <boost/ref.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
NS_LOG_COMPONENT_DEFINE ("CcnxFloodingStrategy");
namespace ns3
{
-
+
+using namespace __ccnx_private;
+
NS_OBJECT_ENSURE_REGISTERED (CcnxFloodingStrategy);
TypeId CcnxFloodingStrategy::GetTypeId (void)
{
- static TypeId tid = TypeId ("ns3::CcnxFloodingStrategy")
+ static TypeId tid = TypeId ("ns3::CcnxFloodingStrategy")
.SetGroupName ("Ccnx")
- .SetParent<Object> ()
+ .SetParent <CcnxForwardingStrategy> ()
+ .AddConstructor <CcnxFloodingStrategy> ()
;
- return tid;
+ return tid;
}
CcnxFloodingStrategy::CcnxFloodingStrategy ()
{
}
-
-
+
bool
-CcnxFloodingStrategy::PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry,
- CcnxFibEntryContainer::type::iterator fibEntry,
- const Ptr<CcnxFace> &incomingFace,
- Ptr<CcnxInterestHeader> &header,
- const Ptr<const Packet> &packet,
- SendCallback ucb)
+CcnxFloodingStrategy::PropagateInterest (const CcnxPitEntry &pitEntry,
+ const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &packet)
{
- //CcnxFibEntryContainer::type::iterator fibEntryArray = GetFib()->LongestPrefixMatch(*header);
- NS_LOG_FUNCTION(this);
-
- //CcnxFibEntryContainer::type::iterator fibEntryArray = GetCcnx()->GetObject<CcnxFib>()->LongestPrefixMatch(*header);
- NS_LOG_INFO(*fibEntry);
-
- int count = 0;
- for(CcnxFibFaceMetricContainer::type::iterator face = fibEntry->m_faces.begin ();
- face != fibEntry->m_faces.end ();
- face++)
+ NS_LOG_FUNCTION (this);
+
+ // Try to work out with just green faces
+ bool greenOk = PropagateInterestViaGreen (pitEntry, incomingFace, header, packet);
+ if (greenOk)
+ return true;
+
+ // boo... :(
+ int propagatedCount = 0;
+
+ BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry.m_faces.get<i_metric> ())
{
- if(face->m_face == incomingFace)
- continue;
- NS_LOG_INFO ("JUST before try add outgoing");
- //Add new outgoing interest to pit entry
- // If PIT entry cannot be created (limit reached or interest already sent), nothing will be forwarded
- //if( _pit.add(VALUE(info.pe), PitOutgoingInterest( *iface, getSimTime(_node), pkt->nonce )) )
- //{
- //GetPit()->Add(*header,fibEntry,face->m_face);
- //GetPit()->modify (GetPit()->end (), CcnxPitEntry::AddOutgoing(face->m_face));
- bool tryResult = GetPit ()->TryAddOutgoing (pitEntry, face->m_face);
- if ( tryResult == false )
- {NS_LOG_INFO("false");
- continue;
+ NS_LOG_DEBUG ("Trying " << boost::cref(metricFace));
+ if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED) // all non-read faces are in front
+ break;
+
+ if (metricFace.m_face == incomingFace)
+ {
+ NS_LOG_DEBUG ("continue (same as incoming)");
+ continue; // same face as incoming, don't forward
}
- else
- NS_LOG_INFO("true");
-
- NS_LOG_INFO("count="<<count);
- ucb (face->m_face, header, packet->Copy());
- count++;
+
+ if (pitEntry.m_incoming.find (metricFace.m_face) != pitEntry.m_incoming.end ())
+ {
+ NS_LOG_DEBUG ("continue (same as previous incoming)");
+ continue; // don't forward to face that we received interest from
+ }
+
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
+ pitEntry.m_outgoing.find (metricFace.m_face);
+
+ if (outgoing != pitEntry.m_outgoing.end () &&
+ outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
+ {
+ NS_LOG_DEBUG ("continue (same as previous outgoing)");
+ continue; // already forwarded before during this retransmission cycle
+ }
+ NS_LOG_DEBUG ("max retx count: " << pitEntry.m_maxRetxCount);
+
+ bool faceAvailable = metricFace.m_face->IsBelowLimit ();
+ if (!faceAvailable) // huh...
+ {
+ continue;
+ }
+
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
+
+ // if (Simulator::GetContext ()==2)
+ // {
+ // NS_LOG_ERROR ("new outgoing entry for " << boost::cref (*metricFace.m_face));
+ // NS_LOG_ERROR ("size: " << pitEntry.m_outgoing.size ());
+ // }
+
+ metricFace.m_face->Send (packet->Copy ());
+
+ propagatedCount++;
}
-
- /*const CcnxFibEntryContainer& s,
-
- for (CcnxFibEntryContainer::type::iterator entry = fibEntryArray.begin ();
- entry != fibEntryArray.end ();
- entry++)
- {
-
- const typename boost::multi_index::index<CcnxFibEntryContainer, Tag>::type& i = get<Tag>(s);
-
- typedef typename CcnxFibEntryContainer::value_type value_type;
-
- for(const CcnxFibEntryContainer& c = i.begin(); c != i.end (); c++)
- {
- c->
- }
-
- for(nth_index<CcnxFibEntryContainer,1>::type::iterator it1=get<i_prefix>(entry).begin();
- it1!=get<i_prefix>(entry).end();++it1)
- {
- //std::cout<<it1->name()<<std::endl;
-
- CcnxFibFaceMetricContainer faceContainer = it1->m_faces;
-
- const typename boost::multi_index::index<CcnxFibFaceMetricContainer, __ccnx_private::i_face>::type& i = get<__ccnx_private::i_face>(faceContainer);
-
- //typedef typename CcnxFibEntryContainer::value_type value_type;
-
- for(const CcnxFibFaceMetricContainer& c = i.begin(); c != i.end (); c++)
- {
- Ptr<CcnxFace> face = c->m_face;
-
- typedef
- Callback<void, const Ptr<CcnxFace> &, const Ptr<CcnxInterestHeader> &, const Ptr<Packet> &>
- SendCallback;
-
- ucb (face, header, packet);
- }
-
- }
-
-
- // obtain a reference to the index tagged by Tag
-
- const typename boost::multi_index::index<MultiIndexContainer,Tag>::type& i=
- get<Tag>(s);
-
- typedef typename MultiIndexContainer::value_type value_type;
-
- // dump the elements of the index to cout
-
- std::copy(i.begin(),i.end(),std::ostream_iterator<value_type>(std::cout));
- */
-
- if(count == 0)
- return false;
- else
- return true;
+
+ NS_LOG_INFO ("Propagated to " << propagatedCount << " faces");
+ return propagatedCount > 0;
}
} //namespace ns3
diff --git a/model/ccnx-flooding-strategy.h b/model/ccnx-flooding-strategy.h
index 5eb7a5d..8be12e9 100644
--- a/model/ccnx-flooding-strategy.h
+++ b/model/ccnx-flooding-strategy.h
@@ -18,18 +18,10 @@
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
*/
-
#ifndef CCNX_FLOODING_STRATEGY_H
#define CCNX_FLOODING_STRATEGY_H
-#include "ns3/packet.h"
-#include "ns3/callback.h"
-#include "ns3/object.h"
-#include "ns3/log.h"
-
#include "ccnx-forwarding-strategy.h"
-#include "ccnx.h"
-#include "ccnx-fib.h"
namespace ns3
{
@@ -38,23 +30,27 @@
class CcnxInterestHeader;
/**
-* \ingroup ccnx
-* \brief Flooding strategy
-*/
-
+ * \ingroup ccnx
+ * \brief Flooding strategy
+ *
+ * \todo Describe
+ */
class CcnxFloodingStrategy : public CcnxForwardingStrategy
{
public:
- static TypeId GetTypeId (void);
-
- CcnxFloodingStrategy ();
-
- bool PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry,
- CcnxFibEntryContainer::type::iterator fibEntry,
- const Ptr<CcnxFace> &incomingFace,
- Ptr<CcnxInterestHeader> &header,
- const Ptr<const Packet> &packet,
- SendCallback ucb);
+ static TypeId GetTypeId (void);
+
+ /**
+ * @brief Default constructor
+ */
+ CcnxFloodingStrategy ();
+
+ // inherited from CcnxForwardingStrategy
+ virtual bool
+ PropagateInterest (const CcnxPitEntry &pitEntry,
+ const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &packet);
};
} //namespace ns3
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index f048e6e..4a1c3a8 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -21,11 +21,23 @@
#include "ns3/assert.h"
-#include "ccnx-route.h"
#include "ccnx-forwarding-strategy.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ccnx-interest-header.h"
+
+#include <boost/ref.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
+
+NS_LOG_COMPONENT_DEFINE ("CcnxForwardingStrategy");
namespace ns3 {
+using namespace __ccnx_private;
+
NS_OBJECT_ENSURE_REGISTERED (CcnxForwardingStrategy);
TypeId CcnxForwardingStrategy::GetTypeId (void)
@@ -33,7 +45,7 @@
static TypeId tid = TypeId ("ns3::CcnxForwardingStrategy")
.SetGroupName ("Ccnx")
.SetParent<Object> ()
- ;
+ ;
return tid;
}
@@ -41,16 +53,69 @@
{
}
+CcnxForwardingStrategy::~CcnxForwardingStrategy ()
+{
+}
+
void
-CcnxForwardingStrategy::SetPit(Ptr<CcnxPit> pit)
+CcnxForwardingStrategy::SetPit (Ptr<CcnxPit> pit)
{
- m_pit = pit;
+ m_pit = pit;
}
-
-Ptr<CcnxPit>
-CcnxForwardingStrategy::GetPit()
+
+bool
+CcnxForwardingStrategy::PropagateInterestViaGreen (const CcnxPitEntry &pitEntry,
+ const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &packet)
{
- return m_pit;
+ // NS_LOG_FUNCTION (this);
+
+ int propagatedCount = 0;
+
+ BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry.m_faces.get<i_metric> ())
+ {
+ if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED ||
+ metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_YELLOW)
+ break; //propagate only to green faces
+
+ if (pitEntry.m_incoming.find (metricFace.m_face) != pitEntry.m_incoming.end ())
+ continue; // don't forward to face that we received interest from
+
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
+ pitEntry.m_outgoing.find (metricFace.m_face);
+
+ if (outgoing != pitEntry.m_outgoing.end () &&
+ outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
+ {
+ continue;
+ }
+
+ bool faceAvailable = metricFace.m_face->IsBelowLimit ();
+ if (!faceAvailable) // huh...
+ {
+ // let's try different green face
+ continue;
+ }
+
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
+
+ metricFace.m_face->Send (packet->Copy ());
+
+ propagatedCount++;
+ break; // propagate only one interest
+ }
+
+ // if (Simulator::GetContext ()==1)
+ // {
+ // if (propagatedCount > 0)
+ // NS_LOG_DEBUG ("Propagate via a green face");
+ // else
+ // NS_LOG_DEBUG ("Can't :(");
+ // }
+ return propagatedCount > 0;
}
-
+
+
} //namespace ns3
diff --git a/model/ccnx-forwarding-strategy.h b/model/ccnx-forwarding-strategy.h
index 3f0f8ae..aff0909 100644
--- a/model/ccnx-forwarding-strategy.h
+++ b/model/ccnx-forwarding-strategy.h
@@ -37,30 +37,64 @@
/**
* \ingroup ccnx
- * \brief Abstract base class for Ccnx forwarding protocols
+ * \brief Abstract base class for CCNx forwarding strategies
*/
class CcnxForwardingStrategy : public Object
{
public:
static TypeId GetTypeId (void);
+ /**
+ * @brief Default constructor
+ */
CcnxForwardingStrategy ();
-
- void SetPit(Ptr<CcnxPit> pit);
-
- typedef
- Callback<void, const Ptr<CcnxFace> &, const Ptr<CcnxInterestHeader> &, const Ptr<Packet> &>
- SendCallback;
+ virtual ~CcnxForwardingStrategy ();
- virtual bool PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry,
- CcnxFibEntryContainer::type::iterator fibEntry,
- const Ptr<CcnxFace> &incomingFace,
- Ptr<CcnxInterestHeader> &header,
- const Ptr<const Packet> &packet,
- SendCallback ucb) = 0;
- Ptr<CcnxPit> GetPit();
+ /**
+ * @brief Base method to propagate the insterest according to the forwarding strategy
+ *
+ * @param pitEntry Reference to PIT entry (reference to corresponding FIB entry inside)
+ * @param incomingFace Incoming face
+ * @param header CcnxInterestHeader
+ * @param packet Original Interest packet
+ * @param sendCallback Send callback
+ *
+ * @return true if interest was successfully propagated, false if all options have failed
+ */
+ virtual bool
+ PropagateInterest (const CcnxPitEntry &pitEntry,
+ const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &packet) = 0;
-private:
+ /**
+ * @brief Set link to PIT for the forwarding strategy
+ *
+ * @param pit pointer to PIT
+ */
+ void
+ SetPit (Ptr<CcnxPit> pit);
+
+protected:
+ /**
+ * @brief Propage interest vie a green interface. Fail, if no green interfaces available
+ *
+ * @param pitEntry Reference to PIT entry (reference to corresponding FIB entry inside)
+ * @param incomingFace Incoming face
+ * @param header CcnxInterestHeader
+ * @param packet Original Interest packet
+ * @param sendCallback Send callback
+ * @return true if interest was successfully propagated, false if all options have failed
+ *
+ * \see PropagateInterest
+ */
+ bool
+ PropagateInterestViaGreen (const CcnxPitEntry &pitEntry,
+ const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &packet);
+
+protected:
Ptr<CcnxPit> m_pit;
};
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index f6295aa..6539ff8 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,27 +177,15 @@
}
void
-CcnxInterestHeader::SetNack (bool isNack)
+CcnxInterestHeader::SetNack (uint32_t nackType)
{
- m_nack = isNack;
+ m_nackType = nackType;
}
-
-bool
-CcnxInterestHeader::IsNack () const
+
+uint32_t
+CcnxInterestHeader::GetNack () const
{
- return m_nack;
-}
-
-void
-CcnxInterestHeader::SetCongested (bool IsCongested)
-{
- m_congested = IsCongested;
-}
-
-bool
-CcnxInterestHeader::IsCongested () const
-{
- return m_congested;
+ return m_nackType;
}
uint32_t
@@ -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..979dfdd 100644
--- a/model/ccnx-interest-header.h
+++ b/model/ccnx-interest-header.h
@@ -202,17 +202,19 @@
uint32_t
GetNonce () const;
+ enum
+ {
+ NORMAL_INTEREST = 0,
+ NACK_LOOP = 10,
+ NACK_CONGESTION = 11,
+ NACK_GIVEUP_PIT = 12,
+ };
+
void
- SetNack (bool isNack);
+ SetNack (uint32_t nackType);
- bool
- IsNack () const;
-
- void
- SetCongested (bool IsCongested);
-
- bool
- IsCongested () const;
+ uint32_t
+ GetNack () const;
//////////////////////////////////////////////////////////////////
@@ -233,8 +235,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 6a4fae6..17dc335 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -33,7 +33,6 @@
#include "ns3/ccnx-header-helper.h"
#include "ccnx-face.h"
-#include "ccnx-route.h"
#include "ccnx-forwarding-strategy.h"
#include "ccnx-interest-header.h"
#include "ccnx-content-object-header.h"
@@ -41,6 +40,11 @@
#include "ccnx-net-device-face.h"
#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+
+using namespace boost::tuples;
+namespace ll = boost::lambda;
NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
@@ -57,20 +61,12 @@
.SetParent<Ccnx> ()
.SetGroupName ("Ccnx")
.AddConstructor<CcnxL3Protocol> ()
- // .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
- // MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
- // .AddTraceSource ("Rx", "Receive ccnx packet from incoming interface.",
- // MakeTraceSourceAccessor (&CcnxL3Protocol::m_rxTrace))
- // .AddTraceSource ("Drop", "Drop ccnx packet",
- // MakeTraceSourceAccessor (&CcnxL3Protocol::m_dropTrace))
- // .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
- // ObjectVectorValue (),
- // MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
- // MakeObjectVectorChecker<CcnxFace> ())
-
- // .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
- // MakeTraceSourceAccessor (&CcnxL3Protocol::m_sendOutgoingTrace))
-
+ .AddAttribute ("BucketLeakInterval",
+ "Interval to leak buckets",
+ StringValue ("10ms"),
+ MakeTimeAccessor (&CcnxL3Protocol::GetBucketLeakInterval,
+ &CcnxL3Protocol::SetBucketLeakInterval),
+ MakeTimeChecker ())
;
return tid;
}
@@ -80,7 +76,6 @@
{
NS_LOG_FUNCTION (this);
- m_rit = CreateObject<CcnxRit> ();
m_pit = CreateObject<CcnxPit> ();
m_contentStore = CreateObject<CcnxContentStore> ();
}
@@ -125,12 +120,22 @@
{
NS_LOG_FUNCTION (this);
+ if (m_bucketLeakEvent.IsRunning ())
+ m_bucketLeakEvent.Cancel ();
+
for (CcnxFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
{
*i = 0;
}
m_faces.clear ();
m_node = 0;
+
+ // Force delete on objects
+ m_forwardingStrategy = 0; // there is a reference to PIT stored in here
+ m_pit = 0;
+ m_contentStore = 0;
+ m_fib = 0;
+
// m_forwardingStrategy = 0;
Object::DoDispose ();
}
@@ -140,7 +145,7 @@
{
NS_LOG_FUNCTION (this);
m_forwardingStrategy = forwardingStrategy;
- // m_forwardingStrategy->SetCcnx (this);
+ m_forwardingStrategy->SetPit (m_pit);
}
Ptr<CcnxForwardingStrategy>
@@ -154,14 +159,13 @@
{
NS_LOG_FUNCTION (this << &face);
- face->SetNode (m_node);
face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
// ask face to register in lower-layer stack
face->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::Receive, this));
m_faces.push_back (face);
- m_faceCounter ++;
+ m_faceCounter++;
return face->GetId ();
}
@@ -170,6 +174,27 @@
{
// ask face to register in lower-layer stack
face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
+
+ // just to be on a safe side. Do the process in two steps
+ std::list<CcnxPitEntryContainer::type::iterator> entriesToRemoves;
+ BOOST_FOREACH (const CcnxPitEntry &pitEntry, *m_pit)
+ {
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind (&CcnxPitEntry::RemoveAllReferencesToFace, ll::_1, face));
+
+ // If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
+ // Thus, we have to remove the whole PIT entry
+ if (pitEntry.m_fibEntry.m_faces.size () == 1 &&
+ pitEntry.m_fibEntry.m_faces.begin ()->m_face == face)
+ {
+ entriesToRemoves.push_back (m_pit->iterator_to (pitEntry));
+ }
+ }
+ BOOST_FOREACH (CcnxPitEntryContainer::type::iterator entry, entriesToRemoves)
+ {
+ m_pit->erase (entry);
+ }
+
CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
NS_ASSERT_MSG (face_it != m_faces.end (), "Attempt to remove face that doesn't exist");
m_faces.erase (face_it);
@@ -206,24 +231,6 @@
return m_faces.size ();
}
-void
-CcnxL3Protocol::TransmittedDataTrace (Ptr<Packet> packet,
- ContentObjectSource type,
- Ptr<Ccnx> ccnx, Ptr<const CcnxFace> face)
-{
- // a "small" inefficiency for logging purposes
- Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
- static CcnxContentObjectTail tail;
- packet->RemoveHeader (*header);
- packet->RemoveTrailer (tail);
-
- m_transmittedDataTrace (header, packet/*payload*/, type, ccnx, face);
-
- packet->AddHeader (*header);
- packet->AddTrailer (tail);
-}
-
-
// Callback from lower layer
void
CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
@@ -249,8 +256,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:
@@ -276,387 +286,266 @@
}
}
+void
+CcnxL3Protocol::OnNack (const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &packet)
+{
+ NS_LOG_FUNCTION (incomingFace << header << packet);
+
+ tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
+ CcnxPitEntry const& pitEntry = ret.get<0> ();
+ bool isNew = ret.get<1> ();
+ bool isDuplicated = ret.get<2> ();
+
+ // NS_ASSERT_MSG (isDuplicated,
+ // "NACK should be a duplicated interest");
+ if (isNew || !isDuplicated) // potential flow
+ {
+ // somebody is doing something bad
+ return;
+ }
+
+ // CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
+
+ if (outFace == pitEntry.m_outgoing.end ())
+ {
+ NS_ASSERT_MSG (false,
+ "Node " << GetObject<Node> ()->GetId () << ", outgoing entry should exist for face " << boost::cref(*incomingFace) << "\n" <<
+ "size: " << pitEntry.m_outgoing.size ());
+
+ return;
+ }
+
+ // This was done in error. Never, never do anything, except normal leakage. This way we ensure that we will not have losses,
+ // at least when there is only one client
+ //
+ // incomingFace->LeakBucketByOnePacket ();
+
+ NS_LOG_ERROR ("Nack on " << boost::cref(*incomingFace));
+
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind (&CcnxPitEntry::SetWaitingInVain, ll::_1, outFace));
+
+ // m_droppedInterestsTrace (header, DROP_CONGESTION, m_node->GetObject<Ccnx> (), incomingFace);
+
+ // If NACK is NACK_GIVEUP_PIT, then neighbor gave up trying to and removed it's PIT entry.
+ // So, if we had an incoming entry to this neighbor, then we can remove it now
+
+ if (header->GetNack () == CcnxInterestHeader::NACK_GIVEUP_PIT)
+ {
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind (&CcnxPitEntry::RemoveIncoming, ll::_1, incomingFace));
+ }
+
+ m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
+ ll::bind (&CcnxFibEntry::UpdateStatus,
+ ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+
+ if (pitEntry.m_incoming.size () == 0) // interest was actually satisfied
+ {
+ // no need to do anything
+ return;
+ }
+
+ if (!pitEntry.AreAllOutgoingInVain ()) // not all ougtoing are in vain
+ {
+ NS_LOG_DEBUG ("Not all outgoing are in vain");
+ // suppress
+ // Don't do anything, we are still expecting data from some other face
+ return;
+ }
+
+ NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
+
+ Ptr<Packet> nonNackInterest = Create<Packet> ();
+ header->SetNack (CcnxInterestHeader::NORMAL_INTEREST);
+ nonNackInterest->AddHeader (*header);
+
+ bool propagated = m_forwardingStrategy->
+ PropagateInterest (pitEntry, incomingFace, header, nonNackInterest);
+
+ // // 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)
+ GiveUpInterest (pitEntry, header);
+}
+
// 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
+ tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
+ CcnxPitEntry const& pitEntry = ret.get<0> ();
+ // bool isNew = ret.get<1> ();
+ bool isDuplicated = ret.get<2> ();
-
-
-
- // 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);
+ NS_LOG_DEBUG ("Sending NACK_LOOP");
+ header->SetNack (CcnxInterestHeader::NACK_LOOP);
+ Ptr<Packet> nack = Create<Packet> ();
+ nack->AddHeader (*header);
- SendInterest(incomingFace, header, packet->Copy());
- return;
- }
+ incomingFace->Send (nack);
-
- // 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<const CcnxContentObjectHeader> contentObjectHeader; // unused for now
+ tie (contentObject, contentObjectHeader) = m_contentStore->Lookup (header);
+ if (contentObject != 0)
+ {
+ NS_ASSERT (contentObjectHeader != 0);
+
+ NS_LOG_LOGIC("Found in cache");
+
+ // TransmittedDataTrace (contentObject, CACHED,
+ // m_node->GetObject<Ccnx> (), incomingFace);
+ incomingFace->Send (contentObject);
+
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ bind (&CcnxPitEntry::SetExpireTime, ll::_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))
- {
- NS_LOG_INFO("Entering (pitEntry != m_pit->end()) && (pitEntry->m_timerExpired == false)");
-
- if(inFace->m_face == NULL)
- NS_LOG_INFO("in face is null");
- if(outFace->m_face == NULL)
- 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));
- }
- }
+ CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
- 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);
+ bool isRetransmitted = false;
- NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
+ if (inFace != pitEntry.m_incoming.end ())
+ {
+ // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
- 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);
- }
-
- m_pit->erase (pitEntry);
- }
- /*}
+ isRetransmitted = true;
+ // 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);
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::var(inFace) = ll::bind (&CcnxPitEntry::AddIncoming, ll::_1, incomingFace));
+ }
+
+ // update PIT entry lifetime
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind (&CcnxPitEntry::UpdateLifetime, ll::_1,
+ header->GetInterestLifetime ()));
+
+ 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),
+ ll::bind (&CcnxFibEntry::UpdateStatus,
+ ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+ }
+
+ if (!isRetransmitted &&
+ pitEntry.AreTherePromisingOutgoingFacesExcept (incomingFace))
+ { // 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, incomingFace, header, packet);
+
+ if (isRetransmitted) //give another chance if retransmitted
+ {
+ // increase max number of allowed retransmissions
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ ll::bind (&CcnxPitEntry::IncreaseAllowedRetxCount, ll::_1));
+
+ // try again
+ propagated = m_forwardingStrategy->
+ PropagateInterest (pitEntry, incomingFace, header, packet);
+ }
+
+ // 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)
+ GiveUpInterest (pitEntry, header);
}
+void
+CcnxL3Protocol::GiveUpInterest (const CcnxPitEntry &pitEntry,
+ Ptr<CcnxInterestHeader> header)
+{
+ Ptr<Packet> packet = Create<Packet> ();
+ header->SetNack (CcnxInterestHeader::NACK_GIVEUP_PIT);
+ packet->AddHeader (*header);
+
+ BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
+ {
+ incoming.m_face->Send (packet->Copy ());
+
+ // m_droppedInterestsTrace (header, DROP_CONGESTION,
+ // m_node->GetObject<Ccnx> (), incomingFace);
+ }
+ // All incoming interests cannot be 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 ()));
+}
+
+
// Processing ContentObjects
-void CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
- Ptr<CcnxContentObjectHeader> &header,
- Ptr<Packet> &payload,
- const Ptr<const Packet> &packet)
+void
+CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
+ Ptr<CcnxContentObjectHeader> &header,
+ Ptr<Packet> &payload,
+ 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
@@ -664,49 +553,55 @@
const CcnxPitEntry &pitEntry = m_pit->Lookup (*header);
// Note that with MultiIndex we need to modify entries indirectly
-
- // 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));
-
- // 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),
+ ll::bind (&CcnxFibEntry::UpdateFaceRtt,
+ ll::_1,
+ incomingFace,
+ 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 "<< boost::cref(*incomingFace) <<" doesn't exist\n");
+
+ // ignore unsolicited data
+ return;
}
+ // Update metric status for the incoming interface in the corresponding FIB entry
+ m_fib->modify (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 &interest, pitEntry.m_incoming)
+ BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
{
- if (interest.m_face == incomingFace) continue;
+ if (incoming.m_face != incomingFace)
+ incoming.m_face->Send (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);
+ // successfull forwarded data trace
}
-
- 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));
- }
-
+ // 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)
{
@@ -714,66 +609,42 @@
// (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
}
}
void
-CcnxL3Protocol::SendInterest (const Ptr<CcnxFace> &face,
- const Ptr<CcnxInterestHeader> &header,
- const Ptr<Packet> &packet)
+CcnxL3Protocol::SetBucketLeakInterval (Time interval)
{
- NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face);
- NS_ASSERT_MSG (face != 0, "Face should never be NULL");
-
- if (face->IsUp ())
- {
- NS_LOG_LOGIC ("Sending via face " << &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);
- }
-}
-
-void
-CcnxL3Protocol::SendContentObject (const Ptr<CcnxFace> &face,
- const Ptr<CcnxContentObjectHeader> &header,
- const Ptr<Packet> &packet)
-{
- 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");
+ m_bucketLeakInterval = interval;
- if (face->IsUp ())
- {
- NS_LOG_LOGIC ("Sending via face " << &face); //
- // m_txTrace (packet, m_node->GetObject<Ccnx> (), face);
- face->Send (packet);
- }
- else
- {
- NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
- // m_dropTrace (packet, INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
- }
+ if (m_bucketLeakEvent.IsRunning ())
+ m_bucketLeakEvent.Cancel ();
+
+ m_bucketLeakEvent = Simulator::Schedule (m_bucketLeakInterval,
+ &CcnxL3Protocol::LeakBuckets, this);
}
-Ptr<CcnxPit>
-CcnxL3Protocol::GetPit()
+Time
+CcnxL3Protocol::GetBucketLeakInterval () const
{
- return m_pit;
+ return m_bucketLeakInterval;
}
-void
-CcnxL3Protocol::ScheduleLeakage()
+void
+CcnxL3Protocol::LeakBuckets ()
{
- m_pit->LeakBuckets();
- Time interval = MilliSeconds (NDN_INTEREST_RESET_PERIOD);
- Simulator::Schedule (interval, &CcnxL3Protocol::ScheduleLeakage, this);
+ // NS_LOG_FUNCTION (this);
+
+ BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces)
+ {
+ face->LeakBucket (m_bucketLeakInterval);
+ }
+
+ m_bucketLeakEvent = Simulator::Schedule (m_bucketLeakInterval,
+ &CcnxL3Protocol::LeakBuckets,
+ this);
}
+
} //namespace ns3
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 3e2c870..f5c19d9 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -127,13 +127,12 @@
void SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy);
Ptr<CcnxForwardingStrategy> GetForwardingStrategy () const;
- virtual void SendInterest (const Ptr<CcnxFace> &face,
- const Ptr<CcnxInterestHeader> &header,
- const Ptr<Packet> &packet);
- virtual void SendContentObject (const Ptr<CcnxFace> &face,
- const Ptr<CcnxContentObjectHeader> &header,
- const Ptr<Packet> &packet);
- virtual void Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p);
+ // virtual void SendInterest (const Ptr<CcnxFace> &face,
+ // const Ptr<const CcnxInterestHeader> &header,
+ // const Ptr<Packet> &packet);
+ // virtual void SendContentObject (const Ptr<CcnxFace> &face,
+ // const Ptr<const CcnxContentObjectHeader> &header,
+ // const Ptr<Packet> &packet);
virtual uint32_t
AddFace (const Ptr<CcnxFace> &face);
@@ -152,8 +151,11 @@
Ptr<CcnxPit> GetPit();
- void ScheduleLeakage();
-protected:
+ // void ScheduleLeakage();
+private:
+ void
+ Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p);
+
/**
* \brief Actual processing of incoming CCNx interests. Note, interests do not have payload
*
@@ -162,11 +164,23 @@
* @param header deserialized Interest header
* @param packet original packet
*/
- virtual void
+ void
OnInterest (const Ptr<CcnxFace> &face,
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
+ */
+ void
+ OnNack (const Ptr<CcnxFace> &face,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &p);
/**
* \brief Actual processing of incoming CCNx content objects
@@ -177,7 +191,7 @@
* @param payload data packet payload
* @param packet original packet
*/
- virtual void
+ void
OnData (const Ptr<CcnxFace> &face,
Ptr<CcnxContentObjectHeader> &header,
Ptr<Packet> &payload,
@@ -196,20 +210,22 @@
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 Set buckets leak interval
+ void
+ SetBucketLeakInterval (Time interval);
- /**
- * \brief A helper function
- */
- void TransmittedDataTrace (Ptr<Packet>,
- ContentObjectSource,
- Ptr<Ccnx>, Ptr<const CcnxFace>);
+ /// \brief Get buckets leak interval
+ Time
+ GetBucketLeakInterval () const;
-
+ /// \brief Periodically generate pre-calculated number of tokens (leak buckets)
+ void
+ LeakBuckets ();
+
+ void
+ GiveUpInterest (const CcnxPitEntry &pitEntry,
+ Ptr<CcnxInterestHeader> header);
+
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;
@@ -218,36 +234,33 @@
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)
-
- TracedCallback<Ptr<const CcnxInterestHeader>,
- Ptr<Ccnx>, Ptr<const CcnxFace> > m_receivedInterestsTrace;
- TracedCallback<Ptr<const CcnxInterestHeader>,
- Ptr<Ccnx>, Ptr<const CcnxFace> > m_transmittedInterestsTrace;
- TracedCallback<Ptr<const CcnxInterestHeader>,
- DropReason,
- Ptr<Ccnx>, Ptr<const CcnxFace> > m_droppedInterestsTrace;
- TracedCallback<Ptr<const CcnxContentObjectHeader>,
- Ptr<const Packet>,/*payload*/
- Ptr<Ccnx>, Ptr<const CcnxFace> > m_receivedDataTrace;
- TracedCallback<Ptr<const CcnxContentObjectHeader>,
- Ptr<const Packet>,/*payload*/
- ContentObjectSource,
- Ptr<Ccnx>, Ptr<const CcnxFace> > m_transmittedDataTrace;
- TracedCallback<Ptr<const CcnxContentObjectHeader>,
- Ptr<const Packet>,/*payload*/
- DropReason,
- Ptr<Ccnx>, Ptr<const CcnxFace> > m_droppedDataTrace;
+ Time m_bucketLeakInterval;
+ EventId m_bucketLeakEvent;
- /**
- * \brief Trace of dropped packets, including reason and all headers
- * \internal
- */
- // TracedCallback<Ptr<const Packet>, DropReason, Ptr<const Ccnx>, Ptr<const CcnxFace> > m_dropTrace;
+ // TracedCallback<Ptr<const CcnxInterestHeader>,
+ // Ptr<Ccnx>, Ptr<const CcnxFace> > m_receivedInterestsTrace;
+ // TracedCallback<Ptr<const CcnxInterestHeader>,
+ // Ptr<Ccnx>, Ptr<const CcnxFace> > m_transmittedInterestsTrace;
+ // TracedCallback<Ptr<const CcnxInterestHeader>,
+ // DropReason,
+ // Ptr<Ccnx>, Ptr<const CcnxFace> > m_droppedInterestsTrace;
+
+ // TracedCallback<Ptr<const CcnxContentObjectHeader>,
+ // Ptr<const Packet>,/*payload*/
+ // Ptr<Ccnx>, Ptr<const CcnxFace> > m_receivedDataTrace;
+ // TracedCallback<Ptr<const CcnxContentObjectHeader>,
+ // Ptr<const Packet>,/*payload*/
+ // ContentObjectSource,
+ // Ptr<Ccnx>, Ptr<const CcnxFace> > m_transmittedDataTrace;
+ // TracedCallback<Ptr<const CcnxContentObjectHeader>,
+ // Ptr<const Packet>,/*payload*/
+ // DropReason,
+ // Ptr<Ccnx>, Ptr<const CcnxFace> > m_droppedDataTrace;
};
} // Namespace ns3
diff --git a/model/ccnx-local-face.cc b/model/ccnx-local-face.cc
index 5020877..0f8ef27 100644
--- a/model/ccnx-local-face.cc
+++ b/model/ccnx-local-face.cc
@@ -25,10 +25,11 @@
#include "ns3/log.h"
#include "ns3/packet.h"
#include "ns3/node.h"
-#include "ns3/pointer.h"
#include "ns3/assert.h"
#include "ns3/ccnx-header-helper.h"
+#include "ns3/ccnx-app.h"
+
#include "ccnx-interest-header.h"
#include "ccnx-content-object-header.h"
@@ -37,24 +38,13 @@
namespace ns3
{
-// NS_OBJECT_ENSURE_REGISTERED (CcnxLocalFace);
-
-// TypeId
-// CcnxLocalFace::GetTypeId (void)
-// {
-// static TypeId tid = TypeId ("ns3::CcnxLocalFace")
-// .SetGroupName ("Ccnx")
-// .SetParent<CcnxFace> ()
-// ;
-// return tid;
-// }
-
-CcnxLocalFace::CcnxLocalFace ()
- : m_onInterest (0)
- , m_onContentObject (0)
+CcnxLocalFace::CcnxLocalFace (Ptr<CcnxApp> app)
+ : CcnxFace (app->GetNode ())
+ , m_app (app)
{
- NS_LOG_FUNCTION (this);
- m_isLocal = true;
+ NS_LOG_FUNCTION (this << app);
+
+ NS_ASSERT (m_app != 0);
}
CcnxLocalFace::~CcnxLocalFace ()
@@ -65,30 +55,17 @@
void
CcnxLocalFace::RegisterProtocolHandler (ProtocolHandler handler)
{
- m_protocolHandler = handler;
-}
+ NS_LOG_FUNCTION (this);
-void
-CcnxLocalFace::SetInterestHandler (InterestHandler onInterest)
-{
- m_onInterest = onInterest;
-}
+ CcnxFace::RegisterProtocolHandler (handler);
-void
-CcnxLocalFace::SetContentObjectHandler (ContentObjectHandler onContentObject)
-{
- m_onContentObject = onContentObject;
+ m_app->RegisterProtocolHandler (MakeCallback (&CcnxFace::Receive, this));
}
void
-CcnxLocalFace::Send (Ptr<Packet> p)
+CcnxLocalFace::SendImpl (Ptr<Packet> p)
{
- NS_LOG_FUNCTION("Local face send");
- NS_LOG_FUNCTION (*p);
- if (!IsUp ())
- {
- return;
- }
+ NS_LOG_FUNCTION (this << p);
try
{
@@ -96,23 +73,27 @@
switch (type)
{
case CcnxHeaderHelper::INTEREST:
- if (!m_onInterest.IsNull ())
- {
- Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();
- p->RemoveHeader (*header);
- m_onInterest (header);
- }
- break;
+ {
+ Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();
+ p->RemoveHeader (*header);
+
+ if (header->GetNack () > 0)
+ m_app->OnNack (header);
+ else
+ m_app->OnInterest (header);
+
+ break;
+ }
case CcnxHeaderHelper::CONTENT_OBJECT:
- if (!m_onContentObject.IsNull ())
- {
- static CcnxContentObjectTail tail;
- Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
- p->RemoveHeader (*header);
- p->RemoveTrailer (tail);
- m_onContentObject (header, p/*payload*/);
- }
- break;
+ {
+ static CcnxContentObjectTail tail;
+ Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
+ p->RemoveHeader (*header);
+ p->RemoveTrailer (tail);
+ m_app->OnContentObject (header, p/*payload*/);
+
+ break;
+ }
}
}
catch (CcnxUnknownHeaderException)
@@ -121,13 +102,6 @@
}
}
-// propagate interest down to ccnx stack
-void
-CcnxLocalFace::ReceiveFromApplication (Ptr<Packet> p)
-{
- m_protocolHandler (Ptr<CcnxFace>(this), p);
-}
-
std::ostream& CcnxLocalFace::Print (std::ostream& os) const
{
os << "dev=local(" << GetId() << ")";
diff --git a/model/ccnx-local-face.h b/model/ccnx-local-face.h
index 664130c..c8c4515 100644
--- a/model/ccnx-local-face.h
+++ b/model/ccnx-local-face.h
@@ -30,6 +30,7 @@
class CcnxInterestHeader;
class CcnxContentObjectHeader;
class Packet;
+class CcnxApp;
/**
* \ingroup ccnx-face
@@ -44,61 +45,32 @@
class CcnxLocalFace : public CcnxFace
{
public:
- typedef Callback<void,const Ptr<const CcnxInterestHeader> &> InterestHandler;
- typedef Callback<void,const Ptr<const CcnxContentObjectHeader> &,
- const Ptr<const Packet> &> ContentObjectHandler;
-
/**
* \brief Default constructor
*/
- CcnxLocalFace ();
+ CcnxLocalFace (Ptr<CcnxApp> app);
virtual ~CcnxLocalFace();
////////////////////////////////////////////////////////////////////
// methods overloaded from CcnxFace
-
- /**
- * \brief This method should be called to establish link with lower layers
- */
virtual void
RegisterProtocolHandler (ProtocolHandler handler);
- /**
- * \brief This method will be called by lower layers to send data to *application*
- */
+protected:
virtual void
- Send (Ptr<Packet> p);
-
+ SendImpl (Ptr<Packet> p);
+
+public:
virtual std::ostream&
Print (std::ostream &os) const;
////////////////////////////////////////////////////////////////////
-
- /**
- * \brief This method will be called by higher layers to send data to *ccnx stack*
- */
- void ReceiveFromApplication (Ptr<Packet> p);
-
- /**
- * \brief Set callback to application
- *
- * \param onInterest InterestHandler to be called when interest arrives on the face. Will be disabled if 0
- */
- void SetInterestHandler (InterestHandler onInterest);
-
- /**
- * \brief Set callback to application
- *
- * \param onContentObject ContentObjectHandler to be called when data arrives. Will be disabled if 0
- */
- void SetContentObjectHandler (ContentObjectHandler onContentObject);
private:
CcnxLocalFace (const CcnxLocalFace &); ///< \brief Disabled copy constructor
CcnxLocalFace& operator= (const CcnxLocalFace &); ///< \brief Disabled copy operator
private:
- InterestHandler m_onInterest;
- ContentObjectHandler m_onContentObject;
+ Ptr<CcnxApp> m_app;
};
std::ostream& operator<< (std::ostream& os, const CcnxLocalFace &localFace);
diff --git a/model/ccnx-name-components.cc b/model/ccnx-name-components.cc
index 438e179..b551733 100644
--- a/model/ccnx-name-components.cc
+++ b/model/ccnx-name-components.cc
@@ -69,25 +69,6 @@
return subComponents;
}
-
-// const ccn_charbuf*
-// Components::GetName () const
-// {
-// return m_value;
-// }
-
-CcnxNameComponents&
-CcnxNameComponents::operator () (const string &s)
-{
- // ccn_name_append_str (m_value,s.c_str());
- m_prefix.push_back (s);
- return *this;
-}
-
-// Components::operator const unsigned char* ()
-// {
-// return m_value->buf;
-// }
void
CcnxNameComponents::Print (std::ostream &os) const
diff --git a/model/ccnx-name-components.h b/model/ccnx-name-components.h
index ea64635..fdffe91 100644
--- a/model/ccnx-name-components.h
+++ b/model/ccnx-name-components.h
@@ -43,12 +43,14 @@
CcnxNameComponents ();
// CcnxNameComponents (const std::string &s);
CcnxNameComponents (const std::list<boost::reference_wrapper<const std::string> > &components);
-
+
+ template<class T>
inline void
- Add (const std::string &s);
-
- CcnxNameComponents&
- operator () (const std::string &s);
+ Add (const T &value);
+
+ template<class T>
+ inline CcnxNameComponents&
+ operator () (const T &value);
const std::list<std::string> &
GetComponents () const;
@@ -108,11 +110,29 @@
{
return m_prefix.size ();
}
-
-void
-CcnxNameComponents::Add (const std::string &s)
+
+template<class T>
+CcnxNameComponents&
+CcnxNameComponents::operator () (const T &value)
{
- (*this) (s);
+ Add (value);
+ return *this;
+}
+
+// template<>
+// void
+// CcnxNameComponents::Add (const std::string &string)
+// {
+// m_prefix.push_back (string);
+// }
+
+template<class T>
+void
+CcnxNameComponents::Add (const T &value)
+{
+ std::ostringstream os;
+ os << value;
+ m_prefix.push_back (os.str ());
}
bool
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index e06a741..468d8f1 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -32,28 +32,17 @@
namespace ns3 {
-// NS_OBJECT_ENSURE_REGISTERED (CcnxNetDeviceFace);
-
-// TypeId
-// CcnxNetDeviceFace::GetTypeId ()
-// {
-// static TypeId tid = TypeId ("ns3::CcnxNetDeviceFace")
-// .SetGroupName ("Ccnx")
-// .SetParent<CcnxFace> ()
-// ;
-// return tid;
-// }
-
/**
* By default, Ccnx face are created in the "down" state. Before
* becoming useable, the user must invoke SetUp on the face
*/
-CcnxNetDeviceFace::CcnxNetDeviceFace (const Ptr<NetDevice> &netDevice)
+CcnxNetDeviceFace::CcnxNetDeviceFace (Ptr<Node> node, const Ptr<NetDevice> &netDevice)
+ : CcnxFace (node)
+ , m_netDevice (netDevice)
{
- NS_LOG_FUNCTION (this);
+ NS_LOG_FUNCTION (this << netDevice);
- m_netDevice = netDevice;
- m_isLocal = false;
+ NS_ASSERT_MSG (m_netDevice != 0, "CcnxNetDeviceFace needs to be assigned a valid NetDevice");
}
CcnxNetDeviceFace::~CcnxNetDeviceFace ()
@@ -61,11 +50,6 @@
NS_LOG_FUNCTION_NOARGS ();
}
-CcnxNetDeviceFace::CcnxNetDeviceFace (const CcnxNetDeviceFace &)
-{
- m_isLocal = false;
-}
-
CcnxNetDeviceFace& CcnxNetDeviceFace::operator= (const CcnxNetDeviceFace &)
{
return *this;
@@ -80,31 +64,26 @@
void
CcnxNetDeviceFace::RegisterProtocolHandler (ProtocolHandler handler)
{
- NS_LOG_FUNCTION(this);
- NS_ASSERT_MSG (m_netDevice != 0, "CcnxNetDeviceFace needs to be assigned NetDevice first");
-
- m_protocolHandler = handler;
+ NS_LOG_FUNCTION (this);
+ CcnxFace::RegisterProtocolHandler (handler);
+
m_node->RegisterProtocolHandler (MakeCallback (&CcnxNetDeviceFace::ReceiveFromNetDevice, this),
CcnxL3Protocol::ETHERNET_FRAME_TYPE, m_netDevice, true/*promiscuous mode*/);
}
void
-CcnxNetDeviceFace::Send (Ptr<Packet> packet)
+CcnxNetDeviceFace::SendImpl (Ptr<Packet> packet)
{
+ NS_LOG_FUNCTION (this << packet);
+
NS_ASSERT_MSG (packet->GetSize () <= m_netDevice->GetMtu (),
"Packet size " << packet->GetSize () << " exceeds device MTU "
- << m_netDevice->GetMtu ()
- << " for Ccnx; fragmentation not supported");
-
- NS_LOG_FUNCTION (*packet);
- if (!IsUp ())
- {
- return;
- }
+ << m_netDevice->GetMtu ()
+ << " for Ccnx; fragmentation not supported");
m_netDevice->Send (packet, m_netDevice->GetBroadcast (),
- CcnxL3Protocol::ETHERNET_FRAME_TYPE);
+ CcnxL3Protocol::ETHERNET_FRAME_TYPE);
}
// callback
@@ -116,7 +95,8 @@
const Address &to,
NetDevice::PacketType packetType)
{
- m_protocolHandler (Ptr<CcnxFace>(this), p);
+ NS_LOG_FUNCTION (device << p << protocol << from << to << packetType);
+ Receive (p);
}
diff --git a/model/ccnx-net-device-face.h b/model/ccnx-net-device-face.h
index e6fbc12..482d5d3 100644
--- a/model/ccnx-net-device-face.h
+++ b/model/ccnx-net-device-face.h
@@ -45,31 +45,26 @@
class CcnxNetDeviceFace : public CcnxFace
{
public:
- // /**
- // * \brief Interface ID
- // *
- // * \return interface ID
- // */
- // static TypeId GetTypeId (void);
-
/**
* \brief Constructor
*
* \param netDevice a smart pointer to NetDevice object to which
* this face will be associate
*/
- CcnxNetDeviceFace (const Ptr<NetDevice> &netDevice);
+ CcnxNetDeviceFace (Ptr<Node> node, const Ptr<NetDevice> &netDevice);
virtual ~CcnxNetDeviceFace();
////////////////////////////////////////////////////////////////////
// methods overloaded from CcnxFace
-
virtual void
RegisterProtocolHandler (ProtocolHandler handler);
+protected:
+ // also from CcnxFace
virtual void
- Send (Ptr<Packet> p);
-
+ SendImpl (Ptr<Packet> p);
+
+public:
virtual std::ostream&
Print (std::ostream &os) const;
////////////////////////////////////////////////////////////////////
diff --git a/model/ccnx-pit-entry-outgoing-face.cc b/model/ccnx-pit-entry-outgoing-face.cc
index ccdfb08..8527779 100644
--- a/model/ccnx-pit-entry-outgoing-face.cc
+++ b/model/ccnx-pit-entry-outgoing-face.cc
@@ -27,11 +27,17 @@
CcnxPitEntryOutgoingFace::CcnxPitEntryOutgoingFace (Ptr<CcnxFace> face)
: m_face (face)
, m_sendTime (Simulator::Now ())
- , m_retxNum (0)
- // , m_nonce (nonce)
- // , m_outstanding (true)
- // , m_waitingInVain (false)
+ , m_retxCount (0)
+ , m_waitingInVain (false)
{
}
+void
+CcnxPitEntryOutgoingFace::UpdateOnRetransmit ()
+{
+ m_sendTime = Simulator::Now ();
+ m_retxCount++;
+ m_waitingInVain = false;
+}
+
} // namespace ns3
diff --git a/model/ccnx-pit-entry-outgoing-face.h b/model/ccnx-pit-entry-outgoing-face.h
index 502f333..c0fe80f 100644
--- a/model/ccnx-pit-entry-outgoing-face.h
+++ b/model/ccnx-pit-entry-outgoing-face.h
@@ -38,14 +38,18 @@
Time m_sendTime; ///< \brief time when the first outgoing interest is sent (for RTT measurements)
///< \todo handle problem of retransmitted interests... Probably, we should include something similar
///< to TimeStamp TCP option for retransmitted (i.e., only lost interests will suffer)
- uint32_t m_retxNum; ///< \brief number of retransmission
- // int m_nonce; ///< \brief nonce of the outgoing Interest
- // bool m_outstanding; ///< \brief flag to indicate that this interest is currently pending
- // bool m_waitingInVain; ///< \brief when flag is set, we do not expect data for this interest, only a small hope that it will happen
+ uint32_t m_retxCount; ///< \brief number of retransmission
+ bool m_waitingInVain; ///< \brief when flag is set, we do not expect data for this interest, only a small hope that it will happen
public:
CcnxPitEntryOutgoingFace (Ptr<CcnxFace> face);
+ /**
+ * @brief Update outgoing entry upon retransmission
+ */
+ void
+ UpdateOnRetransmit ();
+
bool operator== (const CcnxPitEntryOutgoingFace &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..76c7997 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -23,135 +23,124 @@
#include "ccnx-fib.h"
#include "ns3/simulator.h"
+#include "ns3/log.h"
+
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
+
+NS_LOG_COMPONENT_DEFINE ("CcnxPitEntry");
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_timerExpired (false)
- , m_counterExpirations (0)
-{
-}
-
-const CcnxNameComponents &
-CcnxPitEntry::GetPrefix () const
-{
- return *m_prefix;
-}
-
-// CcnxPitEntry::SetFibEntry::SetFibEntry (Ptr<CcnxFibEntry> fib)
-// : m_fib (fib)
-// {
-// }
-
-// void
-// CcnxPitEntry::SetFibEntry::operator() (CcnxPitEntry &entry)
-// {
-// entry.m_fib = m_fib;
-// }
-
-void
-CcnxPitEntry::AddIncoming::operator() (CcnxPitEntry &entry)
-{
- entry.m_incoming.insert (CcnxPitEntryIncomingFace (m_face));
-}
-
-void
-CcnxPitEntry::DeleteIncoming::operator() (CcnxPitEntry &entry)
-{
- entry.m_incoming.erase (m_face);
-}
-
-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)
+ , m_expireTime (Simulator::Now () + expireTime)
+ // , m_timerExpired (false)
+ // , m_counterExpirations (0)
+ , m_maxRetxCount (0)
{
}
void
-CcnxPitEntry::UpdateFibStatus::operator() (CcnxPitEntry &entry)
+CcnxPitEntry::UpdateLifetime (const Time &offsetTime)
{
- NS_ASSERT_MSG (false, "Broken");
- m_fib->modify (m_fib->iterator_to (entry.m_fibEntry),
- CcnxFibEntry::UpdateStatus (m_face, m_status));
+ Time newExpireTime = Simulator::Now () + offsetTime;
+ if (newExpireTime > m_expireTime)
+ m_expireTime = newExpireTime;
+}
+
+CcnxPitEntryIncomingFaceContainer::type::iterator
+CcnxPitEntry::AddIncoming (Ptr<CcnxFace> face)
+{
+ std::pair<CcnxPitEntryIncomingFaceContainer::type::iterator,bool> ret =
+ m_incoming.insert (CcnxPitEntryIncomingFace (face));
+
+ NS_ASSERT_MSG (ret.second, "Something is wrong");
+
+ return ret.first;
}
void
-CcnxPitEntry::EstimateRttAndRemoveFace::operator() (CcnxPitEntry &entry)
+CcnxPitEntry::RemoveIncoming (Ptr<CcnxFace> face)
{
- // 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);
+ m_incoming.erase (face);
}
-}
+
+CcnxPitEntryOutgoingFaceContainer::type::iterator
+CcnxPitEntry::AddOutgoing (Ptr<CcnxFace> face)
+{
+ std::pair<CcnxPitEntryOutgoingFaceContainer::type::iterator,bool> ret =
+ m_outgoing.insert (CcnxPitEntryOutgoingFace (face));
+
+ if (!ret.second)
+ { // outgoing face already exists
+ m_outgoing.modify (ret.first,
+ ll::bind (&CcnxPitEntryOutgoingFace::UpdateOnRetransmit, ll::_1));
+ }
+
+ return ret.first;
+}
+
+void
+CcnxPitEntry::RemoveAllReferencesToFace (Ptr<CcnxFace> face)
+{
+ CcnxPitEntryIncomingFaceContainer::type::iterator incoming =
+ m_incoming.find (face);
+
+ if (incoming != m_incoming.end ())
+ m_incoming.erase (incoming);
+
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
+ m_outgoing.find (face);
+
+ if (outgoing != m_outgoing.end ())
+ m_outgoing.erase (outgoing);
+}
+
+void
+CcnxPitEntry::SetWaitingInVain (CcnxPitEntryOutgoingFaceContainer::type::iterator face)
+{
+ NS_LOG_DEBUG (boost::cref (*face->m_face));
+
+ m_outgoing.modify (face,
+ (&ll::_1)->*&CcnxPitEntryOutgoingFace::m_waitingInVain = true);
+}
+
+bool
+CcnxPitEntry::AreAllOutgoingInVain () const
+{
+ NS_LOG_DEBUG (m_outgoing.size ());
+
+ bool inVain = true;
+ std::for_each (m_outgoing.begin (), m_outgoing.end (),
+ ll::var(inVain) &= (&ll::_1)->*&CcnxPitEntryOutgoingFace::m_waitingInVain);
+
+ NS_LOG_DEBUG ("inVain " << inVain);
+ return inVain;
+}
+
+bool
+CcnxPitEntry::AreTherePromisingOutgoingFacesExcept (Ptr<CcnxFace> face) const
+{
+ bool inVain = true;
+ std::for_each (m_outgoing.begin (), m_outgoing.end (),
+ ll::var(inVain) &=
+ ((&ll::_1)->*&CcnxPitEntryOutgoingFace::m_face == face ||
+ (&ll::_1)->*&CcnxPitEntryOutgoingFace::m_waitingInVain));
+
+ return !inVain;
+}
+
+void
+CcnxPitEntry::IncreaseAllowedRetxCount ()
+{
+ m_maxRetxCount++;
+}
+
+}
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index fa89b5e..162d7a5 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>
@@ -44,7 +45,7 @@
namespace __ccnx_private
{
-// class i_face {};
+class i_retx {};
}
/**
@@ -84,7 +85,11 @@
boost::multi_index::ordered_unique<
boost::multi_index::tag<__ccnx_private::i_face>,
boost::multi_index::member<CcnxPitEntryOutgoingFace, Ptr<CcnxFace>, &CcnxPitEntryOutgoingFace::m_face>
- >
+ >,
+ boost::multi_index::ordered_non_unique<
+ boost::multi_index::tag<__ccnx_private::i_retx>,
+ boost::multi_index::member<CcnxPitEntryOutgoingFace, uint32_t, &CcnxPitEntryOutgoingFace::m_retxCount>
+ >
>
> type;
};
@@ -100,138 +105,146 @@
/**
* \brief PIT entry constructor
* \param prefix Prefix of the PIT entry
+ * \param offsetTime Relative time to the current moment, representing PIT entry lifetime
* \param fibEntry A FIB entry associated with the PIT entry
*/
- CcnxPitEntry (Ptr<CcnxNameComponents> prefix, 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;
- // };
+ CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const Time &offsetTime, const CcnxFibEntry &fibEntry);
/**
- * \brief Unary Function to add incoming interest to the PIT entry
+ * @brief Update lifetime of 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
+ * This function will update PIT entry lifetime to the maximum of the current lifetime and
+ * the lifetime Simulator::Now () + offsetTime
*
- * \param outgoingFace smart pointer to the face of the outgoing interest
- * \returns const iterator to a newly added or updated
- * CcnxPitOutgoingInterest entry
+ * @param offsetTime Relative time to the current moment, representing PIT entry lifetime
*/
- 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;
- };
-
+ void
+ UpdateLifetime (const Time &offsetTime);
+
const CcnxNameComponents &
- GetPrefix () const;
+ GetPrefix () const
+ { return *m_prefix; }
+ /**
+ * @brief Get current expiration time of the record
+ *
+ * @returns current expiration time of the record
+ */
const Time &
- GetExpireTime () const { return m_expireTime; }
+ GetExpireTime () const
+ { return m_expireTime; }
+ /**
+ * @brief Set expiration time on record as `expireTime` (absolute time)
+ *
+ * @param expireTime absolute simulation time of when the record should expire
+ */
+ void
+ SetExpireTime (const Time &expireTime)
+ { m_expireTime = expireTime; }
+
+ /**
+ * @brief Check if nonce `nonce` for the same prefix has already been seen
+ *
+ * @param nonce Nonce to check
+ */
+ bool
+ IsNonceSeen (uint32_t nonce) const
+ { return m_seenNonces.find (nonce) != m_seenNonces.end (); }
+
+ /**
+ * @brief Add `nonce` to the list of seen nonces
+ *
+ * @param nonce nonce to add to the list of seen nonces
+ *
+ * All nonces are stored for the lifetime of the PIT entry
+ */
+ void
+ AddSeenNonce (uint32_t nonce)
+ { m_seenNonces.insert (nonce); }
+
+ /**
+ * @brief Add `face` to the list of incoming faces
+ *
+ * @param face Face to add to the list of incoming faces
+ * @returns iterator to the added entry
+ */
+ CcnxPitEntryIncomingFaceContainer::type::iterator
+ AddIncoming (Ptr<CcnxFace> face);
+
+ /**
+ * @brief Remove incoming entry for face `face`
+ */
+ void
+ RemoveIncoming (Ptr<CcnxFace> face);
+
+ /**
+ * @brief Clear all incoming faces either after all of them were satisfied or NACKed
+ */
+ void
+ ClearIncoming ()
+ { m_incoming.clear (); }
+
+ /**
+ * @brief Add `face` to the list of outgoing faces
+ *
+ * @param face Face to add to the list of outgoing faces
+ * @returns iterator to the added entry
+ */
+ CcnxPitEntryOutgoingFaceContainer::type::iterator
+ AddOutgoing (Ptr<CcnxFace> face);
+
+ /**
+ * @brief Remove all references to face.
+ *
+ * This method should be called before face is completely removed from the stack.
+ * Face is removed from the lists of incoming and outgoing faces
+ */
+ void
+ RemoveAllReferencesToFace (Ptr<CcnxFace> face);
+
+ /**
+ * @brief Flag outgoing face as hopeless
+ */
+ void
+ SetWaitingInVain (CcnxPitEntryOutgoingFaceContainer::type::iterator face);
+
+ /**
+ * @brief Check if all outgoing faces are NACKed
+ */
+ bool
+ AreAllOutgoingInVain () const;
+
+ /*
+ * @brief Similar to AreAllOutgoingInVain, but ignores `face`
+ * \see AreAllOutgoingInVain
+ **/
+ bool
+ AreTherePromisingOutgoingFacesExcept (Ptr<CcnxFace> face) const;
+
+ /**
+ * @brief Increase maximum limit of allowed retransmission per outgoing face
+ */
+ void
+ IncreaseAllowedRetxCount ();
+
+protected:
+
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
Time m_expireTime; ///< \brief Time when PIT entry will be removed
- bool m_timerExpired; ///< \brief flag indicating that PIT timer has expired
- int m_counterExpirations; ///< \brief whether timer is expired (+ number of times timer expired)
-};
+ uint32_t m_maxRetxCount; ///< @brief Maximum allowed number of retransmissions via outgoing faces
+};
} // namespace ns3
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index 7e57b19..1cfa3f9 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -20,37 +20,26 @@
#include "ccnx-pit.h"
#include "ns3/log.h"
+#include "ns3/string.h"
#include "ns3/simulator.h"
#include "ccnx-interest-header.h"
#include "ccnx-content-object-header.h"
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
NS_LOG_COMPONENT_DEFINE ("CcnxPit");
+using namespace boost::tuples;
+using namespace boost;
+
namespace ns3 {
-// NS_OBJECT_ENSURE_REGISTERED (CcnxPit);
+NS_OBJECT_ENSURE_REGISTERED (CcnxPit);
using namespace __ccnx_private;
-// size_t
-// PitEntry::numberOfPromisingInterests(e_pi ) const
-// {
-// size_t count = 0;
-
-// BOOST_FOREACH (const CcnxPitOutgoingInterest &interest, m_outgoingInterests)
-// {
-// }
-// for( PitOutgoingConstIterator i = outgoingInterests.begin();
-// i!=outgoingInterests.end();
-// i++ )
-// {
-// if( !i->waitingInVain ) count++;
-// }
-
-// return count;
-// }
-
-TypeId
+TypeId
CcnxPit::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::CcnxPit")
@@ -59,9 +48,19 @@
.AddConstructor<CcnxPit> ()
.AddAttribute ("CleanupTimeout",
"Timeout defining how frequent RIT should be cleaned up",
- TimeValue (Seconds (1)),
+ StringValue ("1s"),
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 ())
+ .AddAttribute ("PitEntryDefaultLifetime",
+ "Default lifetime of PIT entry (aka default Interest lifetime)",
+ StringValue("4s"),
+ MakeTimeAccessor (&CcnxPit::m_PitEntryDefaultLifetime),
+ MakeTimeChecker ())
;
return tid;
@@ -71,6 +70,25 @@
{
}
+CcnxPit::~CcnxPit ()
+{
+ DoDispose ();
+}
+
+void
+CcnxPit::NotifyNewAggregate ()
+{
+}
+
+void
+CcnxPit::DoDispose ()
+{
+ if (m_cleanupEvent.IsRunning ())
+ m_cleanupEvent.Cancel ();
+
+ clear ();
+}
+
void
CcnxPit::SetCleanupTimeout (const Time &timeout)
{
@@ -79,7 +97,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);
}
@@ -91,21 +109,25 @@
void CcnxPit::CleanExpired ()
{
- NS_LOG_LOGIC ("Cleaning PIT");
+ NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
Time now = Simulator::Now ();
-
- while( !empty() )
+
+ uint32_t count = 0;
+ while (!empty ())
{
- if( get<i_timestamp> ().front ().GetExpireTime () <= now ) // is the record stale?
+ if (get<i_timestamp> ().front ().GetExpireTime () <= now) // is the record stale?
{
- get<i_timestamp> ().pop_front( );
+ 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);
}
@@ -115,49 +137,10 @@
m_fib = fib;
}
-/*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();
- }
-
- CcnxPitEntryContainer::type::iterator entry = insert (end (),
- CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
- *fibEntry));
- return entry;
-}*/
-
-
-
-bool
-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()]);
-
- 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;
-
- 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 ());
@@ -168,51 +151,46 @@
return *entry;
}
-CcnxPitEntryContainer::type::iterator
-CcnxPit::Lookup (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator &outFibEntry)
+boost::tuple<const CcnxPitEntry&, 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;
-}
-
-void
-CcnxPit::LeakBuckets( )
-{
- for( PitBucketIterator it=m_bucketsPerFace.begin();
- it != m_bucketsPerFace.end();
- it++ )
{
- it->second = std::max( 0.0, it->second - leakSize[it->first] );
- }
-}
-
-void
-CcnxPit::LeakBucket(Ptr<CcnxFace> face, int amount )
-{
- m_bucketsPerFace[face->GetId()] = std::max( 0.0, m_bucketsPerFace[face->GetId()] - amount );
-}
+ 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 ()),
+ header.GetInterestLifetime ().IsZero ()?m_PitEntryDefaultLifetime
+ : 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);
+}
} // namespace ns3
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index ed724fe..0d1132e 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 {
@@ -91,9 +92,8 @@
// typedef std::map<int,int> PitCounter;
// typedef std::map<int,int>::iterator PitCounterIterator;
- typedef std::map<int,double> PitBucket;
- typedef std::map<int,double>::iterator PitBucketIterator;
-
+typedef std::map<int,double> PitBucket;
+typedef std::map<int,double>::iterator PitBucketIterator;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
@@ -117,11 +117,11 @@
*/
CcnxPit ();
- /*CcnxPitEntryContainer::type::iterator
- Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face);*/
+ /**
+ * \brief Destructor
+ */
+ virtual ~CcnxPit ();
- bool
- 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
@@ -134,26 +134,34 @@
/**
* \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);
-
- // Reset pending state in outgoing interests
- // void resetPendingState( PitEntry &pe );
+ Time GetPitEntryPruningTimeout () const
+ {
+ return m_PitEntryPruningTimout;
+ }
+
+ /**
+ * \brief Set FIB table
+ */
+ void SetFib (Ptr<CcnxFib> fib);
- // // Check if there are any interfaces that we haven't sent data to yet
- // bool areFreeInterfaces( PitEntry &pe, int interface );
+protected:
+ // inherited from Object class
+ virtual void NotifyNewAggregate ();
+ virtual void DoDispose ();
+
+private:
+ /** \brief Remove expired records from PIT */
+ void CleanExpired ();
- // Periodically generate pre-calculated number of tokens (leak buckets)
- void LeakBuckets( );
-
- // Selectively leak a bucket
- void LeakBucket (Ptr<CcnxFace> face, int amount);
-
/**
* \brief Set cleanup timeout
*
@@ -170,28 +178,26 @@
*/
Time GetCleanupTimeout () const;
- /**
- * \brief Set FIB table
- */
- void SetFib (Ptr<CcnxFib> fib);
-
-public:
- PitBucket maxBucketsPerFace; // maximum number of buckets. Automatically computed based on link capacity
- // // averaging over 1 second (bandwidth * 1second)
- PitBucket leakSize; // size of a periodic bucket leak
-
-private:
- /** \brief Remove expired records from PIT */
- void CleanExpired ();
-
friend std::ostream& operator<< (std::ostream& os, const CcnxPit &fib);
private:
Time m_cleanupTimeout; ///< \brief Configurable timeout of how often cleanup events are working
EventId m_cleanupEvent; ///< \brief Cleanup event
+ // configuration variables. Check implementation of GetTypeId for more details
+ Time m_PitEntryPruningTimout;
+ Time m_PitEntryDefaultLifetime;
+
Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
- PitBucket m_bucketsPerFace; ///< \brief pending interface counter per face
+ // PitBucket m_bucketsPerFace; ///< \brief pending interface counter per face
+
+ // /**
+ // * \brief maximum number of buckets. Automatically computed based on link capacity
+ // * averaging over 1 second (bandwidth * 1second)
+ // */
+ // PitBucket maxBucketsPerFace;
+
+ // PitBucket leakSize; ///< size of a periodic bucket leak
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/model/ccnx-rit.cc b/model/ccnx-rit.cc
index 6a7e556..2a1b7f0 100644
--- a/model/ccnx-rit.cc
+++ b/model/ccnx-rit.cc
@@ -75,7 +75,29 @@
{
}
-CcnxRit::~CcnxRit( ) { }
+CcnxRit::~CcnxRit( )
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_cleanupEvent.IsRunning ())
+ m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events
+
+ clear ();
+}
+
+void
+CcnxRit::NotifyNewAggregate ()
+{
+}
+
+void
+CcnxRit::DoDispose ()
+{
+ if (m_cleanupEvent.IsRunning ())
+ m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events
+
+ clear ();
+}
void
CcnxRit::SetRitTimeout (const Time &timeout)
@@ -97,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);
}
@@ -110,8 +132,8 @@
bool
CcnxRit::WasRecentlySatisfied (const CcnxInterestHeader &header)
{
- NS_LOG_FUNCTION_NOARGS ();
- std::pair<CcnxRitByNonce::type::iterator,CcnxRitByNonce::type::iterator>
+ // NS_LOG_FUNCTION_NOARGS ();
+ std::pair<CcnxRitByNonce::type::iterator,CcnxRitByNonce::type::iterator>
entries = get<nonce> ().equal_range (header.GetNonce ());
if (entries.first == end ())
@@ -131,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 (
@@ -144,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);
}
diff --git a/model/ccnx-rit.h b/model/ccnx-rit.h
index ba5a133..501f409 100644
--- a/model/ccnx-rit.h
+++ b/model/ccnx-rit.h
@@ -188,6 +188,11 @@
*/
Time GetCleanupTimeout () const;
+protected:
+ // inherited from Object class
+ virtual void NotifyNewAggregate ();
+ virtual void DoDispose ();
+
private:
/**
* \brief Periodic even to clean up stalled entries
diff --git a/model/ccnx.cc b/model/ccnx.cc
index 0fe4b31..af551a6 100644
--- a/model/ccnx.cc
+++ b/model/ccnx.cc
@@ -38,4 +38,8 @@
return tid;
}
+Ccnx::~Ccnx ()
+{
+}
+
} // namespace ns3
diff --git a/model/ccnx.h b/model/ccnx.h
index cafa354..38c2f74 100644
--- a/model/ccnx.h
+++ b/model/ccnx.h
@@ -22,7 +22,6 @@
#define _CCNX_H_
#include "ns3/object.h"
-#include "ns3/socket.h"
#include "ns3/callback.h"
namespace ns3 {
@@ -49,11 +48,10 @@
class i_mru {};
}
-#define MILLI_SECOND 1
-#define SECOND 1000
// default data size
-#define NDN_DEFAULT_DATA_SIZE 1024
-#define NDN_INTEREST_RESET_PERIOD (10*MILLI_SECOND)
+// #define NDN_DEFAULT_DATA_SIZE 1024
+// #define NDN_INTEREST_RESET_PERIOD (10*MILLI_SECOND)
+
/**
* \defgroup ccnx NDN abstraction
*
@@ -81,61 +79,62 @@
class Ccnx : public Object
{
public:
- enum ForwardingStrategy
+ enum ForwardingStrategy
{
- NDN_FLOODING = 1,
- NDN_BESTROUTE = 2,
- NDN_RANKING = 3
+ NDN_FLOODING = 1,
+ NDN_BESTROUTE = 2,
+ NDN_RANKING = 3
};
-
+
/**
* \brief Interface ID
*
* \return interface ID
*/
static TypeId GetTypeId ();
+ virtual ~Ccnx ();
- /**
- * \brief Send an Interest packet to a specified face
- *
- * \param face face where to send this packet
- * \param header Interest header
- * \param packet fully prepared CCNx packet to send
- *
- * Higher-level layers (forwarding strategy in particular) call this
- * method to send a packet down the stack to the MAC and PHY layers.
- */
- virtual void
- SendInterest (const Ptr<CcnxFace> &face,
- const Ptr<CcnxInterestHeader> &header,
- const Ptr<Packet> &packet) = 0;
+ // /**
+ // * \brief Send an Interest packet to a specified face
+ // *
+ // * \param face face where to send this packet
+ // * \param header Interest header
+ // * \param packet fully prepared CCNx packet to send
+ // *
+ // * Higher-level layers (forwarding strategy in particular) call this
+ // * method to send a packet down the stack to the MAC and PHY layers.
+ // */
+ // virtual void
+ // SendInterest (const Ptr<CcnxFace> &face,
+ // const Ptr<const CcnxInterestHeader> &header,
+ // const Ptr<Packet> &packet) = 0;
- /**
- * \brief Send a ContentObject packet to a specified face
- *
- * \param face face where to send this packet
- * \param header ContentObject header
- * \param packet fully prepared CCNx packet to send
- *
- * Higher-level layers (forwarding strategy in particular) call this
- * method to send a packet down the stack to the MAC and PHY layers.
- */
- virtual void
- SendContentObject (const Ptr<CcnxFace> &face,
- const Ptr<CcnxContentObjectHeader> &header,
- const Ptr<Packet> &packet) = 0;
+ // /**
+ // * \brief Send a ContentObject packet to a specified face
+ // *
+ // * \param face face where to send this packet
+ // * \param header ContentObject header
+ // * \param packet fully prepared CCNx packet to send
+ // *
+ // * Higher-level layers (forwarding strategy in particular) call this
+ // * method to send a packet down the stack to the MAC and PHY layers.
+ // */
+ // virtual void
+ // SendContentObject (const Ptr<CcnxFace> &face,
+ // const Ptr<const CcnxContentObjectHeader> &header,
+ // const Ptr<Packet> &packet) = 0;
- /**
- * \brief Lower layers calls this method after demultiplexing
- *
- * Lower-layer-dependent implementation of CcnxFace will do actual work
- * to set up demultiplexing and call this function as a callback
- *
- * \param face face from which packet came from
- * \param p the packet
- */
- virtual void
- Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p) = 0;
+ // /**
+ // * \brief Lower layers calls this method after demultiplexing
+ // *
+ // * Lower-layer-dependent implementation of CcnxFace will do actual work
+ // * to set up demultiplexing and call this function as a callback
+ // *
+ // * \param face face from which packet came from
+ // * \param p the packet
+ // */
+ // virtual void
+ // Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p) = 0;
/**
* \brief Register a new forwarding strategy to be used by this Ccnx
diff --git a/wscript b/wscript
index f256b39..7da13ff 100644
--- a/wscript
+++ b/wscript
@@ -30,7 +30,7 @@
def build(bld):
deps = ['core', 'network', 'point-to-point',
'topology-read','internet','applications',
- 'point-to-point-layout']
+ 'point-to-point-layout', 'netanim']
if bld.env['ENABLE_PYTHON_BINDINGS']:
deps.append ('visualizer')
@@ -77,13 +77,16 @@
obj = bld.create_ns3_program('annotated-topology', ['NDNabstraction', 'point-to-point-layout'])
obj.source = 'examples/annotated-topology-read-example.cc'
- obj = bld.create_ns3_program('interest-header', ['NDNabstraction'])
+ obj = bld.create_ns3_program('interest-header-example', ['NDNabstraction'])
obj.source = 'examples/interest-header-example.cc'
- obj = bld.create_ns3_program('ccnx-sprint-topology', ['NDNabstraction', 'point-to-point-layout'])
+ obj = bld.create_ns3_program('packet-sizes', ['NDNabstraction'])
+ obj.source = 'examples/packet-sizes.cc'
+
+ obj = bld.create_ns3_program('ccnx-sprint-topology', ['NDNabstraction'])
obj.source = 'examples/sprint-topology.cc'
- obj = bld.create_ns3_program('ccnx-abilene-topology', ['NDNabstraction', 'point-to-point-layout'])
+ obj = bld.create_ns3_program('ccnx-abilene-topology', ['NDNabstraction'])
obj.source = 'examples/abilene-topology.cc'
# for path in ["examples"]: