examples: New example with custom strategy "random-load-balancer-strategy"
Based on Steve DiBenedetto's tutorial code https://github.com/dibenede/ndn-tutorial-gec21
diff --git a/examples/ndn-load-balancer.cpp b/examples/ndn-load-balancer.cpp
new file mode 100644
index 0000000..46ea740
--- /dev/null
+++ b/examples/ndn-load-balancer.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2015 Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+// ndn-load-balancer.cpp
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/ndnSIM-module.h"
+
+#include "ndn-load-balancer/random-load-balancer-strategy.hpp"
+
+using namespace ns3;
+
+/**
+ * This scenario simulates a load balancer topology (using topology reader module)
+ *
+ * ( ) ----- ( ) ---- (consumer)
+ * |
+ * ------ ( ) -----
+ * | |
+ * (producer) ---- (producer)
+ *
+ * All links are 1Mbps with propagation 10ms delay.
+ *
+ * FIB is populated using NdnGlobalRoutingHelper.
+ *
+ * Consumer requests data from the two producers with frequency 10 interests per
+ * second (interests contain constantly increasing sequence number).
+ *
+ * For every received interest, a load balancing operation is performed
+ * (based on a custom forwarding strategy) and the selected producer
+ * replies with a data packet, containing 1024 bytes of virtual payload.
+ *
+ * To run scenario and see what is happening, use the following command:
+ *
+ * NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-load-balancer
+ */
+
+using ns3::ndn::StackHelper;
+using ns3::ndn::AppHelper;
+using ns3::ndn::GlobalRoutingHelper;
+using ns3::ndn::StrategyChoiceHelper;
+using ns3::AnnotatedTopologyReader;
+
+int
+main(int argc, char* argv[])
+{
+ CommandLine cmd;
+ cmd.Parse(argc, argv);
+
+ AnnotatedTopologyReader topologyReader("", 25);
+ topologyReader.SetFileName("src/ndnSIM/examples/topologies/topo-load-balancer.txt");
+ topologyReader.Read();
+
+ // Install NDN stack on all nodes
+ StackHelper ndnHelper;
+ ndnHelper.InstallAll();
+
+ // Installing global routing interface on all nodes
+ GlobalRoutingHelper ndnGlobalRoutingHelper;
+ ndnGlobalRoutingHelper.InstallAll();
+
+ // Getting containers for the consumer/producer
+ Ptr<Node> producer1 = Names::Find<Node>("UCLA-1");
+ Ptr<Node> producer2 = Names::Find<Node>("UCLA-2");
+ NodeContainer consumerNodes;
+ consumerNodes.Add(Names::Find<Node>("CSU-1"));
+
+ // Install NDN applications
+ std::string prefix = "/ucla/hello";
+
+ AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
+ consumerHelper.SetPrefix(prefix);
+ consumerHelper.SetAttribute("Frequency", StringValue("100")); // 100 interests a second
+ consumerHelper.Install(consumerNodes);
+
+ AppHelper producerHelper("ns3::ndn::Producer");
+ producerHelper.SetPrefix(prefix);
+ producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
+ producerHelper.Install(producer1);
+ producerHelper.Install(producer2);
+
+ // Install random-load-balancer forwarding strategy in
+ // node UCLA-HUB
+ StrategyChoiceHelper strategyChoiceHelper;
+ strategyChoiceHelper.Install<nfd::fw::RandomLoadBalancerStrategy>(Names::Find<Node>("UCLA-HUB"),
+ prefix);
+
+ // Add /prefix origins to ndn::GlobalRouter
+ ndnGlobalRoutingHelper.AddOrigins(prefix, producer1);
+ ndnGlobalRoutingHelper.AddOrigins(prefix, producer2);
+
+ // Calculate and install FIBs
+ GlobalRoutingHelper::CalculateRoutes();
+
+ Simulator::Stop(Seconds(1.0));
+
+ Simulator::Run();
+ Simulator::Destroy();
+
+ return 0;
+}
diff --git a/examples/ndn-load-balancer/random-load-balancer-strategy.cpp b/examples/ndn-load-balancer/random-load-balancer-strategy.cpp
new file mode 100644
index 0000000..6083dd3
--- /dev/null
+++ b/examples/ndn-load-balancer/random-load-balancer-strategy.cpp
@@ -0,0 +1,100 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "random-load-balancer-strategy.hpp"
+
+#include <boost/random/uniform_int_distribution.hpp>
+
+#include <ndn-cxx/util/random.hpp>
+
+#include "core/logger.hpp"
+
+NFD_LOG_INIT("RandomLoadBalancerStrategy");
+
+namespace nfd {
+namespace fw {
+
+const Name
+ RandomLoadBalancerStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/random-load-balancer");
+
+RandomLoadBalancerStrategy::RandomLoadBalancerStrategy(Forwarder& forwarder, const Name& name)
+ : Strategy(forwarder, name)
+{
+}
+
+RandomLoadBalancerStrategy::~RandomLoadBalancerStrategy()
+{
+}
+
+static bool
+canForwardToNextHop(shared_ptr<pit::Entry> pitEntry, const fib::NextHop& nexthop)
+{
+ return pitEntry->canForwardTo(*nexthop.getFace());
+}
+
+static bool
+hasFaceForForwarding(const fib::NextHopList& nexthops, shared_ptr<pit::Entry>& pitEntry)
+{
+ return std::find_if(nexthops.begin(), nexthops.end(), bind(&canForwardToNextHop, pitEntry, _1))
+ != nexthops.end();
+}
+
+void
+RandomLoadBalancerStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
+ shared_ptr<fib::Entry> fibEntry,
+ shared_ptr<pit::Entry> pitEntry)
+{
+ NFD_LOG_TRACE("afterReceiveInterest");
+
+ if (pitEntry->hasUnexpiredOutRecords()) {
+ // not a new Interest, don't forward
+ return;
+ }
+
+ const fib::NextHopList& nexthops = fibEntry->getNextHops();
+
+ // Ensure there is at least 1 Face is available for forwarding
+ if (!hasFaceForForwarding(nexthops, pitEntry)) {
+ this->rejectPendingInterest(pitEntry);
+ return;
+ }
+
+ fib::NextHopList::const_iterator selected;
+ do {
+ boost::random::uniform_int_distribution<> dist(0, nexthops.size() - 1);
+ const size_t randomIndex = dist(m_randomGenerator);
+
+ uint64_t currentIndex = 0;
+
+ for (selected = nexthops.begin(); selected != nexthops.end() && currentIndex != randomIndex;
+ ++selected, ++currentIndex) {
+ }
+ } while (!canForwardToNextHop(pitEntry, *selected));
+
+ this->sendInterest(pitEntry, selected->getFace());
+}
+
+} // namespace fw
+} // namespace nfd
diff --git a/examples/ndn-load-balancer/random-load-balancer-strategy.hpp b/examples/ndn-load-balancer/random-load-balancer-strategy.hpp
new file mode 100644
index 0000000..2d45831
--- /dev/null
+++ b/examples/ndn-load-balancer/random-load-balancer-strategy.hpp
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDNSIM_EXAMPLES_NDN_LOAD_BALANCER_RANDOM_LOAD_BALANCER_STRATEGY_HPP
+#define NDNSIM_EXAMPLES_NDN_LOAD_BALANCER_RANDOM_LOAD_BALANCER_STRATEGY_HPP
+
+#include <boost/random/mersenne_twister.hpp>
+#include "face/face.hpp"
+#include "fw/strategy.hpp"
+
+namespace nfd {
+namespace fw {
+
+class RandomLoadBalancerStrategy : public Strategy {
+public:
+ RandomLoadBalancerStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
+
+ virtual ~RandomLoadBalancerStrategy();
+
+ virtual void
+ afterReceiveInterest(const Face& inFace, const Interest& interest,
+ shared_ptr<fib::Entry> fibEntry, shared_ptr<pit::Entry> pitEntry);
+
+public:
+ static const Name STRATEGY_NAME;
+
+protected:
+ boost::random::mt19937 m_randomGenerator;
+};
+
+} // namespace fw
+} // namespace nfd
+
+#endif // NDNSIM_EXAMPLES_NDN_LOAD_BALANCER_RANDOM_LOAD_BALANCER_STRATEGY_HPP
diff --git a/examples/topologies/topo-load-balancer.txt b/examples/topologies/topo-load-balancer.txt
new file mode 100644
index 0000000..f05ec96
--- /dev/null
+++ b/examples/topologies/topo-load-balancer.txt
@@ -0,0 +1,52 @@
+# topo-load-balancer.txt
+
+#
+# /----\
+# |CSU |
+# <----> |HUB | <---->
+# ^ \----/ ^
+# | | 1Mbps/10ms delay
+# v v
+# /----\ /--------\
+# |UCLA| |Consumer|
+# | HUB| | CSU-1 |
+# <----> \----/ <----> \--------/
+# ^ ^
+# | |
+# v v
+# /--------\ /--------\
+# |Producer| |Producer|
+# | UCLA-1 | | UCLA-2 |
+# \--------/ \--------/
+#
+
+# any empty lines and lines starting with '#' symbol is ignored
+#
+# The file should contain exactly two sections: router and link, each starting with the corresponding keyword
+#
+# router section defines topology nodes and their relative positions (e.g., to use in visualizer)
+router
+
+# each line in this section represents one router and should have the following data
+# node comment yPos xPos
+CSU-1 NA 3 5
+CSU-HUB NA 5 3
+UCLA-HUB NA 3 1
+UCLA-1 NA 0 0
+UCLA-2 NA 0 2
+
+# Note that `node` can be any string. It is possible to access to the node by name using Names::Find, see examples.
+
+# link section defines point-to-point links between nodes and characteristics of these links
+link
+
+# Each line should be in the following format (only first two are required, the rest can be omitted)
+# srcNode dstNode bandwidth metric delay queue
+# bandwidth: link bandwidth
+# metric: routing metric
+# delay: link delay
+# queue: MaxPackets for transmission queue on the link (both directions)
+CSU-1 CSU-HUB 1Mbps 1 10ms 10
+CSU-HUB UCLA-HUB 1Mbps 1 10ms 10
+UCLA-HUB UCLA-1 1Mbps 1 10ms 10
+UCLA-HUB UCLA-2 1Mbps 1 10ms 10