Update of BlackholeSprint scenario. Extending CcnxStackHelper API
(InstallRouteTo can now accept prefix as a parameter)
diff --git a/examples/base-experiment.h b/examples/base-experiment.h
new file mode 100644
index 0000000..7a9e4bf
--- /dev/null
+++ b/examples/base-experiment.h
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011,2012 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 BASE_EXPERIMENT_H
+#define BASE_EXPERIMENT_H
+
+#include "ns3/rocketfuel-topology-reader.h"
+
+class BaseExperiment
+{
+public:
+ BaseExperiment ()
+ : m_rand (0,52)
+ , reader (0)
+ { }
+
+ ~BaseExperiment ()
+ {
+ if (reader != 0) delete reader;
+ }
+
+ void
+ ConfigureTopology ()
+ {
+ Names::Clear ();
+ cout << "Configure Topology\n";
+ if (reader != 0) delete reader;
+ reader = new RocketfuelWeightsReader ("/sprint");
+
+ string weights ("./src/NDNabstraction/examples/sprint-pops.weights");
+ string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
+ string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
+
+ reader->SetFileName (positions);
+ reader->SetFileType (RocketfuelWeightsReader::POSITIONS);
+ reader->Read ();
+
+ reader->SetFileName (weights);
+ reader->SetFileType (RocketfuelWeightsReader::WEIGHTS);
+ reader->Read ();
+
+ reader->SetFileName (latencies);
+ reader->SetFileType (RocketfuelWeightsReader::LATENCIES);
+ reader->Read ();
+
+ reader->Commit ();
+ }
+
+ void InstallCcnxStack ()
+ {
+ InternetStackHelper stack;
+ Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
+ stack.SetRoutingHelper (ipv4RoutingHelper);
+ stack.Install (reader->GetNodes ());
+
+ reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
+
+ // Install CCNx stack
+ cout << "Installing CCNx stack\n";
+ CcnxStackHelper ccnxHelper;
+ ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
+ ccnxHelper.EnableLimits (true, Seconds(0.1));
+ ccnxHelper.SetDefaultRoutes (false);
+ ccnxHelper.InstallAll ();
+
+ // // Populate FIB based on IPv4 global routing controller
+ ccnxHelper.InstallFakeGlobalRoutes ();
+ ccnxHelper.InstallRoutesToAll ();
+ }
+
+ void InstallIpStack ()
+ {
+ InternetStackHelper stack;
+ stack.Install (reader->GetNodes ());
+ reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
+
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ }
+
+ void
+ GenerateRandomPairs (uint16_t numStreams)
+ {
+ m_pairs.clear ();
+ // map<uint32_t, set<uint32_t> > streams;
+ m_usedNodes.clear ();
+
+ uint16_t createdStreams = 0;
+ uint16_t guard = 0;
+ while (createdStreams < numStreams && guard < (numeric_limits<uint16_t>::max ()-1))
+ {
+ guard ++;
+
+ uint32_t node1_num = m_rand.GetValue ();
+ uint32_t node2_num = m_rand.GetValue ();
+
+ if (node1_num == node2_num)
+ continue;
+
+ if (m_usedNodes.count (node1_num) > 0 ||
+ m_usedNodes.count (node2_num) > 0 )
+ {
+ continue; // don't reuse nodes
+ }
+
+ m_usedNodes.insert (node1_num);
+ m_usedNodes.insert (node2_num);
+
+ m_pairs.push_back (make_tuple (node1_num, node2_num));
+ createdStreams ++;
+ }
+ }
+
+ void
+ Run (const Time &finishTime)
+ {
+ cout << "Run Simulation.\n";
+ Simulator::Stop (finishTime);
+ // Simulator::Schedule (Seconds (1.0), PrintTime);
+ Simulator::Run ();
+ Simulator::Destroy ();
+ cout << "Done.\n";
+ }
+
+ UniformVariable m_rand;
+ RocketfuelWeightsReader *reader;
+
+ list<tuple<uint32_t,uint32_t> > m_pairs;
+ set<uint32_t> m_usedNodes;
+};
+
+#endif
diff --git a/examples/blackhole-sprint.cc b/examples/blackhole-sprint.cc
index f97be29..a6afb82 100644
--- a/examples/blackhole-sprint.cc
+++ b/examples/blackhole-sprint.cc
@@ -27,7 +27,6 @@
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/random-variable.h"
-#include <iostream>
#include <sstream>
#include <map>
#include <list>
@@ -50,209 +49,74 @@
Simulator::Schedule (Seconds (1.0), PrintTime);
}
+#include "base-experiment.h"
-class Experiment
+class Experiment : public BaseExperiment
{
public:
- Experiment ()
- : m_reader ("/sprint") { }
-
- void
- ConfigureTopology ()
- {
- Names::Clear ();
-
- string weights ("./src/NDNabstraction/examples/sprint-pops.weights");
- string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
- string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
-
- m_reader.SetFileName (positions);
- m_reader.SetFileType (RocketfuelWeightsReader::POSITIONS);
- m_reader.Read ();
-
- m_reader.SetFileName (weights);
- m_reader.SetFileType (RocketfuelWeightsReader::WEIGHTS);
- m_reader.Read ();
-
- m_reader.SetFileName (latencies);
- m_reader.SetFileType (RocketfuelWeightsReader::LATENCIES);
- m_reader.Read ();
-
- m_reader.Commit ();
- NS_ASSERT_MSG (m_reader.LinksSize () != 0, "Problems reading the topology file. Failing.");
-
- NS_LOG_INFO("Nodes = " << m_reader.GetNodes ().GetN());
- NS_LOG_INFO("Links = " << m_reader.LinksSize ());
-
- // ------------------------------------------------------------
- // -- Read topology data.
- // --------------------------------------------
-
- InternetStackHelper stack;
- Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
- stack.SetRoutingHelper (ipv4RoutingHelper);
- stack.Install (m_reader.GetNodes ());
-
- m_reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-
- // Install CCNx stack
- NS_LOG_INFO ("Installing CCNx stack");
- CcnxStackHelper ccnxHelper;
- ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
- ccnxHelper.EnableLimits (true, Seconds(0.1));
- ccnxHelper.SetDefaultRoutes (false);
- ccnxHelper.InstallAll ();
-
- m_rand = UniformVariable (0, m_reader.GetNodes ().GetN());
- m_linkRand = UniformVariable(0, m_reader.LinksSize());
- }
-
- void
- ConfigureRouting ()
- {
- CcnxStackHelper ccnxHelper;
- // // Populate FIB based on IPv4 global routing controller
- ccnxHelper.InstallFakeGlobalRoutes ();
- ccnxHelper.InstallRoutesToAll ();
- }
-
-public:
- void
- Run (const Time &finishTime)
- {
- cout << "Run Simulation.\n";
- Simulator::Stop (finishTime);
- //Simulator::Schedule (Seconds (1.0), PrintTime);
- Simulator::Run ();
- Simulator::Destroy ();
- cout << "Done.\n";
- }
-
//We are creating 10 pairs of producer-hijacker and everybody else is a consumer
ApplicationContainer
- AddApplications(uint32_t numOfPairs)
+ AddApplications ()
{
- NS_LOG_INFO("Adding applications");
ApplicationContainer apps;
-
- list<uint32_t > usedNodes;
- list<uint32_t >::iterator listIterator;
- list<uint32_t >::iterator listIterator2;
-
- uint32_t producerNodeId;
- uint32_t hijackerNodeId;
- for(uint32_t pairCount = 0; pairCount < numOfPairs; pairCount++)
+ list<string> prefixes;
+
+ // Create Producers/Hijackers
+ for (list<tuple<uint32_t,uint32_t> >::iterator i = m_pairs.begin (); i != m_pairs.end (); i++)
{
- NS_LOG_INFO("pairCount = "<<pairCount);
- while(true)
- {
- producerNodeId = m_rand.GetValue ();
- hijackerNodeId = m_rand.GetValue ();
-
- bool unique = true;
- for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator)
- {
- if((*listIterator == producerNodeId) || (*listIterator == hijackerNodeId))
- {
- NS_LOG_INFO("NonUnique");
- unique = false;
- }
- }
-
- if(unique == true)
- {
- usedNodes.push_back(producerNodeId);
- usedNodes.push_back(hijackerNodeId);
- break;
- }
- }
-
- NS_LOG_INFO("Producer #" << producerNodeId);
- Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (producerNodeId));
- CcnxAppHelper producerHelper ("ns3::CcnxProducer");
- producerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-
- apps.Add(producerHelper.Install (node1));
+ uint32_t node1_num = i->get<0> ();
+ uint32_t node2_num = i->get<1> ();
- NS_LOG_INFO("Hijacker # "<<hijackerNodeId);
- Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (hijackerNodeId));
- CcnxAppHelper hijackerHelper ("ns3::CcnxHijacker");
- hijackerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-
- apps.Add(hijackerHelper.Install (node1));
-
- /*NS_LOG_INFO("Consumers");
- for(uint32_t j = 0; j<m_reader.GetNodes().GetN();j++)
- {
- //NS_LOG_INFO("j="<<j);
- bool consumer = true;
- for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator)
- {
- if(*listIterator == j)
- {
- consumer = false;
- NS_LOG_INFO(j<<" CANNOT be CONSUMER");
- break;
- }
- }
-
- if(consumer == true)
- {
- Ptr<Node> node3 = Names::Find<Node> ("/sprint", lexical_cast<string> (j));
-
- CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
- consumerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
- consumerHelper.SetAttribute ("MeanRate", StringValue ("1Kbps"));
- consumerHelper.SetAttribute ("Size", StringValue ("2"));
-
- apps.Add(consumerHelper.Install (node3));
- }
- }*/
- }
-
- NS_LOG_INFO("Consumers");
- for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator,++listIterator)
- {
- for(uint32_t j = 0; j<m_reader.GetNodes().GetN();j++)
- {
- //NS_LOG_INFO("j="<<j);
- bool consumer = true;
- for(listIterator2=usedNodes.begin(); listIterator2 != usedNodes.end(); ++listIterator2)
- {
- if(*listIterator2 == j)
- {
- consumer = false;
- NS_LOG_INFO(j<<" CANNOT be a CONSUMER");
- break;
- }
- }
-
- if(consumer == true)
- {
- Ptr<Node> node3 = Names::Find<Node> ("/sprint", lexical_cast<string> (j));
- Ptr<Node> node4 = Names::Find<Node> ("/sprint", lexical_cast<string> (*listIterator));
+ Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
+ Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
- CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
- NS_LOG_INFO("Node = " << *listIterator);
- consumerHelper.SetPrefix ("/" + lexical_cast<string> (node4->GetId ()));
- consumerHelper.SetAttribute ("MeanRate", StringValue ("1Kbps"));
- consumerHelper.SetAttribute ("Size", StringValue ("2"));
+ // node1 legitimate producer
+ // node2 "fake" producer
+
+ string prefix = "/" + lexical_cast<string> (node1->GetId ());
+
+ CcnxAppHelper legitimateProducerHelper ("ns3::CcnxProducer");
+ legitimateProducerHelper.SetPrefix (prefix);
+ apps.Add
+ (legitimateProducerHelper.Install (node1));
- apps.Add(consumerHelper.Install (node3));
- }
+ CcnxAppHelper fakeProducerHelper ("ns3::CcnxHijacker");
+ fakeProducerHelper.SetPrefix (prefix);
+ apps.Add
+ (fakeProducerHelper.Install (node2));
+
+ // one more trick. Need to install route to hijacker (aka "hijacker announces itself as a legitimate producer")
+ CcnxStackHelper::InstallRouteTo (prefix, node2);
+
+ prefixes.push_back (prefix); // remember prefixes that consumers will be requesting
+ }
+
+ // All consumers request exactly 10 packets, to convert number interests packets to requested size:
+ // size = 1040 * (max_number_of_packets-1) / 1024 / 1024
+ double requestSize = 1040.0 * (10 - 1) / 1024.0 / 1024.0;
+
+ // Create Consumers
+ NodeContainer nodes = reader->GetNodes ();
+ for (NodeContainer::Iterator node = nodes.Begin (); node != nodes.End (); node++)
+ {
+ uint32_t namedId = lexical_cast<uint32_t> (Names::FindName (*node));
+ if (m_usedNodes.count (namedId) > 0)
+ continue;
+
+ CcnxAppHelper consumerHelper ("ns3::CcnxConsumerCbr");
+ BOOST_FOREACH (const string &prefix, prefixes)
+ {
+ consumerHelper.SetPrefix (prefix);
+ consumerHelper.SetAttribute ("MeanRate", StringValue ("8Kbps")); // this is about 1 interest a second
+ consumerHelper.SetAttribute ("Size", DoubleValue(requestSize));
+
+ apps.Add
+ (consumerHelper.Install (*node));
}
- }
-
-
+ }
return apps;
}
-
- UniformVariable m_rand;
- UniformVariable m_linkRand;
-
-private:
- RocketfuelWeightsReader m_reader;
};
int
@@ -260,48 +124,45 @@
{
cout << "Begin blackhole scenario\n";
- Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("2Mbps"));
- Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("100"));
+ Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("100Mbps"));
+ Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("2000"));
- Time finishTime = Seconds (20.0);
-
-
+ Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("attributes.xml"));
+ Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
+ Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml"));
+
+ uint32_t maxRuns = 1;
+ uint32_t startRun = 0;
CommandLine cmd;
- cmd.AddValue ("finish", "Finish time", finishTime);
+ cmd.AddValue ("start", "Initial run number", startRun);
+ cmd.AddValue ("runs", "Number of runs", maxRuns);
cmd.Parse (argc, argv);
- Experiment experiment;
+ // ConfigStore config;
+ // config.ConfigureDefaults ();
+ Experiment experiment;
for (uint32_t i = 0; i < 80; i++)
{
Config::SetGlobal ("RngRun", IntegerValue (i));
cout << "seed = " << SeedManager::GetSeed () << ", run = " << SeedManager::GetRun () << endl;
Experiment experiment;
+ experiment.GenerateRandomPairs (10);
cout << "Run " << i << endl;
string prefix = "run-" + lexical_cast<string> (i) + "-";
experiment.ConfigureTopology ();
- ApplicationContainer apps = experiment.AddApplications (10);
- experiment.ConfigureRouting ();
-
- /*ApplicationContainer apps = experiment.AddApplications ();
-
- for (uint32_t i = 0; i < apps.GetN () / 2; i++)
- {
- cout << "From " << apps.Get (i*2)->GetNode ()->GetId ()
- << " to " << apps.Get (i*2 + 1)->GetNode ()->GetId ();
- cout << "\n";
- }
- */
-
+ experiment.InstallCcnxStack ();
+ ApplicationContainer apps = experiment.AddApplications ();
+
//tracing
CcnxTraceHelper traceHelper;
- traceHelper.EnableRateL3All (prefix + "rate-trace.log");
+ // traceHelper.EnableRateL3All (prefix + "rate-trace.log");
traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumer", prefix + "consumers-seqs.log");
- experiment.Run (finishTime);
+ experiment.Run (Seconds(20.0));
}
cout << "Finish blackhole scenario\n";
diff --git a/examples/congestion-pop.cc b/examples/congestion-pop.cc
index fcfcc99..ae28ad8 100644
--- a/examples/congestion-pop.cc
+++ b/examples/congestion-pop.cc
@@ -30,13 +30,6 @@
#include "ns3/applications-module.h"
#include "ns3/config-store.h"
-#include <iostream>
-#include <sstream>
-#include <map>
-#include <list>
-#include <set>
-#include "ns3/rocketfuel-topology-reader.h"
-
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
@@ -53,110 +46,11 @@
// Simulator::Schedule (Seconds (1.0), PrintTime);
// }
-class Experiment
+#include "base-experiment.h"
+
+class Experiment : public BaseExperiment
{
public:
- Experiment ()
- : m_rand (0,52)
- , reader (0)
- { }
-
- ~Experiment ()
- {
- if (reader != 0) delete reader;
- }
-
- void
- ConfigureTopology ()
- {
- Names::Clear ();
- cout << "Configure Topology\n";
- if (reader != 0) delete reader;
- reader = new RocketfuelWeightsReader ("/sprint");
-
- string weights ("./src/NDNabstraction/examples/sprint-pops.weights");
- string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
- string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
-
- reader->SetFileName (positions);
- reader->SetFileType (RocketfuelWeightsReader::POSITIONS);
- reader->Read ();
-
- reader->SetFileName (weights);
- reader->SetFileType (RocketfuelWeightsReader::WEIGHTS);
- reader->Read ();
-
- reader->SetFileName (latencies);
- reader->SetFileType (RocketfuelWeightsReader::LATENCIES);
- reader->Read ();
-
- reader->Commit ();
- }
-
- void InstallCcnxStack ()
- {
- InternetStackHelper stack;
- Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
- stack.SetRoutingHelper (ipv4RoutingHelper);
- stack.Install (reader->GetNodes ());
-
- reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-
- // Install CCNx stack
- cout << "Installing CCNx stack\n";
- CcnxStackHelper ccnxHelper;
- ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
- ccnxHelper.EnableLimits (true, Seconds(0.1));
- ccnxHelper.SetDefaultRoutes (false);
- ccnxHelper.InstallAll ();
-
- // // Populate FIB based on IPv4 global routing controller
- ccnxHelper.InstallFakeGlobalRoutes ();
- ccnxHelper.InstallRoutesToAll ();
- }
-
- void InstallIpStack ()
- {
- InternetStackHelper stack;
- stack.Install (reader->GetNodes ());
- reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-
- Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
- }
-
- void
- GenerateRandomPairs (uint16_t numStreams)
- {
- m_pairs.clear ();
- // map<uint32_t, set<uint32_t> > streams;
- set<uint32_t> usedNodes;
-
- uint16_t createdStreams = 0;
- uint16_t guard = 0;
- while (createdStreams < numStreams && guard < (numeric_limits<uint16_t>::max ()-1))
- {
- guard ++;
-
- uint32_t node1_num = m_rand.GetValue ();
- uint32_t node2_num = m_rand.GetValue ();
-
- if (node1_num == node2_num)
- continue;
-
- if (usedNodes.count (node1_num) > 0 ||
- usedNodes.count (node2_num) > 0 )
- {
- continue; // don't reuse nodes
- }
-
- usedNodes.insert (node1_num);
- usedNodes.insert (node2_num);
-
- m_pairs.push_back (make_tuple (node1_num, node2_num));
- createdStreams ++;
- }
- }
-
ApplicationContainer
AddCcnxApplications ()
{
@@ -226,23 +120,6 @@
return apps;
}
-
-
- void
- Run (const Time &finishTime)
- {
- cout << "Run Simulation.\n";
- Simulator::Stop (finishTime);
- // Simulator::Schedule (Seconds (1.0), PrintTime);
- Simulator::Run ();
- Simulator::Destroy ();
- cout << "Done.\n";
- }
-
- UniformVariable m_rand;
- RocketfuelWeightsReader *reader;
-
- list<tuple<uint32_t,uint32_t> > m_pairs;
};
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 ()
{
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index b4cdbc6..6cd3745 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -151,8 +151,8 @@
* \param faceId Face index
* \param metric Routing metric
*/
- void
- AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const;
+ static void
+ AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric);
/**
* \brief Add forwarding entry in FIB
@@ -162,8 +162,8 @@
* \param face Face
* \param metric Routing metric
*/
- void
- AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const;
+ static void
+ AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric);
/**
* \brief Set flag indicating necessity to install default routes in FIB
@@ -177,28 +177,36 @@
* This method adds fake routes to all nodes, where each route is /32 and IPv4 address equal to node number.
* For example, node 5 will have direct route to 0.0.0.5.
*/
- void
+ static void
InstallFakeGlobalRoutes ();
- void
+ static void
InstallFakeGlobalRoutesImpl ();
/**
- * \brief Installs CCNx route to `node` based on fake IPv4 routes
+ * \brief Install CCNx route to `node` based on fake IPv4 routes
*
* Actual route is "/<nodeId>"
*
* \param node Pointer to a node, which should be reached from all other nodes
*/
- void
+ static void
InstallRouteTo (Ptr<Node> node);
/**
- * \brief Installs CCNx route to all nodes based on fake IPv4 routes
+ * \brief Install CCNx route to /prefix which is installed on `node'
+ *
+ * Normally, prefix is /<node->GetId()>. Other values may be used in black-holing scenarios
+ */
+ static void
+ InstallRouteTo (const std::string &prefix, Ptr<Node> node);
+
+ /**
+ * \brief Install CCNx route to all nodes based on fake IPv4 routes
*
* \see InstallRouteTo
*/
- void
+ static void
InstallRoutesToAll ();
private: