Update of BlackholeSprint scenario. Extending CcnxStackHelper API
(InstallRouteTo can now accept prefix as a parameter)
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 62c5f82..3714f64 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -19,41 +19,6 @@
* Ilya Moiseenko <iliamo@cs.ucla.edu>
*/
-/**
- * \ingroup ccnx
- * \defgroup CcnxStackModel Ccnx Stack Model
- *
- * \section CcnxStackTracingModel Tracing in the Ccnx Stack
- *
- * The ccnx stack provides a number of trace sources in its various
- * protocol implementations. These trace sources can be hooked using your own
- * custom trace code, or you can use our helper functions in some cases to
- * arrange for tracing to be enabled.
- *
- * \subsection CcnxStackCcnxTracingModel Tracing in Ccnx
- *
- * The Ccnx layer three protocol provides three trace hooks. These are the
- * "Tx" (ns3::CcnxL3Protocol::m_txTrace), "Rx" (ns3::CcnxL3Protocol::m_rxTrace)
- * and "Drop" (ns3::CcnxL3Protocol::m_dropTrace) trace sources.
- *
- * The "Tx" trace is fired in a number of situations, all of which indicate that
- * a given packet is about to be sent down to a given ns3::CcnxFace.
- *
- * - \todo list Tx trace events
- *
- * The "Rx" trace is fired when a packet is passed from the device up to the
- * ns3::CcnxL3Protocol::Receive function.
- *
- * - In the receive function, the CcnxFaceList is iterated, and if the
- * CcnxFace corresponding to the receiving device is found to be in the
- * UP state, the trace is fired.
- *
- * The "Drop" trace is fired in any case where the packet is dropped (in both
- * the transmit and receive paths).
- *
- * - \todo list Drop trace events
- */
-
#include "ns3/assert.h"
#include "ns3/log.h"
#include "ns3/object.h"
@@ -91,43 +56,11 @@
#include <limits>
#include <map>
#include <boost/foreach.hpp>
-
-#define NDN_DEFAULT_DATA_SIZE 1024
+#include <boost/lexical_cast.hpp>
NS_LOG_COMPONENT_DEFINE ("CcnxStackHelper");
namespace ns3 {
-
-// Things are going to work differently here with respect to trace
-// file handling than in most places because the Tx and Rx trace
-// sources we are interested in are going to multiplex receive and
-// transmit callbacks for all Ccnx and face pairs through one
-// callback. We want packets to or from each distinct pair to go to
-// an individual file, so we have got to demultiplex the Ccnx and face
-// pair into a corresponding Ptr<PcapFileWrapper> at the callback.
-//
-// A complication in this situation is that the trace sources are
-// hooked on a protocol basis. There is no trace source hooked by an
-// Ccnx and face pair. This means that if we naively proceed to hook,
-// say, a drop trace for a given Ccnx with face 0, and then hook for
-// Ccnx with face 1 we will hook the drop trace twice and get two
-// callbacks per event. What we need to do is to hook the event once,
-// and that will result in a single callback per drop event, and the
-// trace source will provide the face which we filter on in the trace
-// sink.
-//
-// This has got to continue to work properly after the helper has been
-// destroyed; but must be cleaned up at the end of time to avoid
-// 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;
-
-// 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_limitsEnabled (false)
@@ -265,7 +198,7 @@
void
-CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const
+CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric)
{
NS_LOG_LOGIC ("[" << node->GetId () << "]$ route add " << prefix << " via " << *face << " metric " << metric);
@@ -277,7 +210,7 @@
}
void
-CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const
+CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric)
{
Ptr<Node> node = Names::Find<Node> (nodeName);
NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
@@ -291,275 +224,6 @@
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);
-
- NS_ASSERT_MSG (node != 0, "Node does not exist");
-
- Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
- Ptr<CcnxFib> fib = node->GetObject<CcnxFib> ();
- Ptr<CcnxFace> face = ccnx->GetFace (faceId);
- NS_ASSERT_MSG (node != 0, "Face with ID [" << faceId << "] does not exist on node [" << nodeName << "]");
-
- 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);
-
-// //
-// // 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);
-// }
-
-// 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);
-
-// //
-// // 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);
-// }
-
-// 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");
-
-// 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;
-// }
-
-// 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;
-// }
-
-// *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;
-// }
-
-// *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;
-// }
-
-// 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;
-
-// std::string filename;
-// if (explicitFilename)
-// {
-// filename = prefix;
-// }
-// else
-// {
-// filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
-// }
-
-// 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\"");
-// }
-
-// 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;
-
-// //
-// // 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;
-// }
void
CcnxStackHelper::InstallFakeGlobalRoutesImpl ()
@@ -599,9 +263,12 @@
void
CcnxStackHelper::InstallRouteTo (Ptr<Node> destNode)
{
- std::ostringstream destPrefix;
- destPrefix << "/" << destNode->GetId ();
+ InstallRouteTo (boost::lexical_cast<std::string> (destNode->GetId ()), destNode);
+}
+void
+CcnxStackHelper::InstallRouteTo (const std::string &prefix, Ptr<Node> destNode)
+{
Ipv4Address destIpv4 = Ipv4Address(destNode->GetId ());
for (NodeList::Iterator node = NodeList::Begin ();
@@ -634,11 +301,12 @@
Ptr<CcnxFace> face = ccnx->GetFaceByNetDevice (netDevice);
NS_ASSERT_MSG (face != 0, "Definitely should never happen. Call the president");
- AddRoute (*node, destPrefix.str(), face, entry.GetMetric ());
+ AddRoute (*node, prefix, face, entry.GetMetric ());
}
}
}
+
void
CcnxStackHelper::InstallRoutesToAll ()
{