**breaking** mini-ndn: re-design

refs: #5062

Everything is now done through examples like Mininet.
bin/minindn no longer provided as a binary installed in the system
bin/minindnedit GUI: will no longer be maintained
Remove cluster edition, will be re-introduced later

Change-Id: Id4ef137cb2a04d1b0dd24d01941757363bbf7d26
This commit is contained in:
Ashlesh Gawande committed 2019-12-05 15:13:01 -06:00
1 parent 8ae870a591
commit 6c86e30f63
85 files changed
+3576 -5654

No files matched your search

+15 -20
View File
@@ -1,24 +1,19 @@
# Python
build
crypto
ChronoSync
dist
doc/html
doc/latex
.DS_Store
examples
infoedit
jndn
Mini_NDN.egg-info
mininet
NFD
NLSR
ndn-cpp
ndn-cxx
ndn-js
ndn-tools
openflow
PyNDN2
PSync
util
.vagrant
*.pyc
# Docs
docs/html
docs/latex
docs/_build
# Misc
.DS_Store
mininet
ndn-src
openflow
# Vagrant
.vagrant
-92
View File
@@ -1,92 +0,0 @@
Mini-NDN Installation Instructions
================================
### What equipment will I need?
For this guide, you will need a laptop/desktop with a recent version
of a Linux distro such as Ubuntu or any of its variants. Fedora is not
officially supported but has also been reported to work for some
users. For this guide, the _Ubuntu 18.04 LTS_ release was used.
Also, note that you'll need administrative privileges in order to
download and install extra packages and also to execute **Mini-NDN**.
### Installing **Mini-NDN**
NOTE: Mini-NDN, while providing a high level of emulation of hosts,
requires programs to be installed onto your computer. It will not work
if they are not installed. If you do not want NDN software installed
onto your computer, you can use a virtual machine, which can be quite
simply set up with the provided vagrantfile.
If you have all the dependencies (see sections below) installed simply clone this repository and run:
./install.sh -i
else if you don't have the dependencies, the following command will install them from source along with Mini-NDN:
./install.sh -a
If you want to install the dependencies manually or from the Named Data PPA, follow the instructions below:
### Installing NDN
Each node in **Mini-NDN** will run the official implementation of NDN installed on your system. The following dependencies are needed:
Mini-NDN uses NFD, NLSR, and ndn-tools.
To install NFD:
https://named-data.net/doc/NFD/current/INSTALL.html
To install NLSR:
https://named-data.net/doc/NLSR/current/INSTALL.html
To install ndn-tools:
https://github.com/named-data/ndn-tools
Note that all three of these can be installed from the Named Data PPA. Instructions for setting it up can
be found in the NFD insallation instructions. Note that PPA and installs from source **cannot** be mixed.
###Special Instructions for PPA Installs
If you are using a custom nfd.conf file in an experiment, you should place it in /usr/local/etc/ndn/
rather than /etc/ndn/. This is to avoid a bug from the default configuration file for the PPA, which
is incompatiable with Mini-NDN.
### Installing Mininet
**Mini-NDN** is based on Mininet. To install Mininet:
First, clone Mininet from github:
git clone --depth 1 https://github.com/mininet/mininet.git
After Mininet source is on your system, run the following command to
install Mininet core dependencies and Open vSwitch:
./util/install.sh -nv
To check if Mininet is working correctly, run this test:
sudo mn --test pingall
This will print out a series of statements that show the test setup
and the results of the test. Look for `Results:` two-thirds of the way
down where it will indicate the percentage of dropped packets.
Your results should show "0% dropped (2/2 received)".
### Installing Infoedit
Infoedit is used to edit configuration files such as NFD configuration
file.
To install infoedit:
https://github.com/NDN-Routing/infoedit
### Verification
You can use these steps to verify your installation:
1. Issue the command: `sudo minindn --experiment=pingall --nPings=50`
2. When the `mini-ndn>` CLI prompt appears, the experiment has finished. On the Mini-NDN CLI, issue the command `exit` to exit the experiment.
3. Issue the command: `grep -c content /tmp/minindn/*/ping-data/*.txt`. Each file should report a count of 50.
4. Issue the command: `grep -c timeout /tmp/minindn/*/ping-data/*.txt`. Each file should report a count of 0.
+9 -10
View File
@@ -7,10 +7,9 @@ If you are new to the NDN community of software generally, read the
### What is Mini-NDN?
Mini-NDN is a lightweight networking emulation tool that enables testing, experimentation, and
research on the NDN platform. Based on [Mini-CCNx](https://github.com/chesteve/mn-ccnx) which
is a fork of [Mininet](https://github.com/mininet/mininet), Mini-NDN uses the NDN libraries,
NFD, NLSR, and tools released by the [NDN project](http://named-data.net/codebase/platform/)
to emulate an NDN network on a single system.
research on the NDN platform based on [Mininet](https://github.com/mininet/mininet).
Mini-NDN uses the NDN libraries, NFD, NLSR, and tools released by the
[NDN project](http://named-data.net/codebase/platform/) to emulate an NDN network on a single system.
Mini-NDN is open and free software licensed under the GPL 3.0 license. Mini-NDN is free to all
users and developers. For more information about licensing details and limitations,
@@ -25,9 +24,9 @@ Bug reports and feedback are highly appreciated and can be made through our
### Documentation
* [Installation](INSTALL.md)
* [Getting Started](docs/GETTING-STARTED.md)
* [Mini-NDN Edit](docs/GUI.md)
* [Running Experiments](docs/EXPERIMENTS.md)
* [Mini-NDN Redmine](http://redmine.named-data.net/projects/mini-ndn)
* [Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md)
Please refer to http://minindn.memphis.edu/ or [docs/index.rst](docs/index.rst) for installation, usage, and other documentation.
The documentation can be built using:
./install.sh -d
and is available under `docs/_build/html`.
Vendored
+14 -5
View File
@@ -2,18 +2,27 @@
# vi: set ft=ruby :
$script = <<SCRIPT
ln -s /vagrant /home/vagrant/mini-ndn
git clone --depth 1 https://github.com/named-data/mini-ndn.git
cd mini-ndn
# Check if install.sh is present or someone just copied the Vagrantfile directly
if [[ -f /home/vagrant/mini-ndn/install.sh ]]; then
pushd /home/vagrant/mini-ndn
else
# Remove the symlink
rm /home/vagrant/mini-ndn
git clone --depth 1 https://github.com/named-data/mini-ndn.git
pushd mini-ndn
fi
./install.sh -a
SCRIPT
Vagrant.configure(2) do |config|
config.vm.box = "bento/ubuntu-16.04"
config.vm.box = "ubuntu/bionic64"
config.vm.provision "shell", privileged: false, inline: $script
config.vm.provider "virtualbox" do |vb|
vb.name = "mini-ndn_box"
vb.memory = 2000
vb.cpus = 2
vb.memory = 4096
vb.cpus = 4
end
end
-462
View File
@@ -1,462 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
#
# This file incorporates work covered by the following copyright and
# permission notice:
#
# Mininet 2.3.0d1 License
#
# Copyright (c) 2013-2016 Open Networking Laboratory
# Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
# The Leland Stanford Junior University
#
# Original authors: Bob Lantz and Brandon Heller
#
# We are making Mininet available for public use and benefit with the
# expectation that others will use, modify and enhance the Software and
# contribute those enhancements back to the community. However, since we
# would like to make the Software available for broadest use, with as few
# restrictions as possible permission is hereby granted, free of charge, to
# any person obtaining a copy of this Software to deal in the Software
# under the copyrights without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# The name and trademarks of copyright holder(s) may NOT be used in
# advertising or publicity pertaining to the Software or any derivatives
# without specific, written prior permission.
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.log import setLogLevel, output, info, error, warn
from mininet.link import TCLink
from mininet.util import ipStr, ipParse
from mininet.examples.cluster import MininetCluster, RoundRobinPlacer, ClusterCleanup
from mininet.examples.clustercli import ClusterCLI
from ndn import ExperimentManager
from ndn.experiments.experiment import Experiment
from ndn.ndn_host import NdnHost, CpuLimitedNdnHost, RemoteNdnHost
from ndn.conf_parser import parse_hosts, parse_switches, parse_links
from ndn.remote_ndn_link import RemoteNdnLink, RemoteGRENdnLink
from ndn.placer import GuidedPlacer, PopulatePlacement
from ndn.nfd import Nfd
from ndn.util import ssh, scp, MiniNDNCLI, ProgramOptions
import os.path, time
import shutil
import argparse
import datetime
from os.path import expanduser
import sys
import signal
from subprocess import call
import glob
from functools import partial
import re
try:
import argcomplete
except ImportError:
pass
VERSION_NUMBER = "0.4.0"
INSTALL_DIR='/usr/local/etc/mini-ndn/'
class PrintExperimentNames(argparse.Action):
def __init__(self, option_strings, dest, nargs=0, help=None):
super(PrintExperimentNames, self).__init__(option_strings=option_strings, dest=dest, nargs=nargs, help=help)
def __call__(self, parser, namespace, values, option_string=None):
experimentNames = ExperimentManager.getExperimentNames()
print("Mini-NDN experiments:")
for experiment in experimentNames:
print(" {}".format(experiment))
sys.exit(0)
def createResultsDir(resultDir, faces, rType):
if faces == 0:
faces = "all"
routingChoice = "/{}/".format(rType)
resultDir = "{}/{}/faces-{}".format(resultDir, routingChoice, faces)
resultDir = os.path.abspath(resultDir)
if not os.path.isdir(resultDir):
os.makedirs(resultDir)
else:
warn("Results directory ({}) already exists!".format(resultDir))
sys.exit(1)
info("Results will be stored at: {}".format(resultDir))
return resultDir
def parse_args():
parser = argparse.ArgumentParser(prog='minindn')
# nargs='?' required here since optional argument
parser.add_argument('tempfile', nargs='?', default=INSTALL_DIR + 'default-topology.conf',
help="If no template_file is given, topologies/default-topology.conf (given sample file) will be used.")
parser.add_argument("--ctime", type=int, default=60,
help="Specify convergence time for the topology (Default: 60 seconds)")
parser.add_argument("--experiment", choices=[experiment for experiment in ExperimentManager.getExperimentNames()],
help="Runs the specified experiment")
parser.add_argument("--faces", type=int, default=3,
help="Specify number of max faces per prefix for NLSR 0-60")
parser.add_argument("--routing", dest="routingType", default='link-state', choices=['link-state', 'hr', 'dry'],
help="""choices for routing are 'link-state' for link state, 'hr' for hyperbolic, and 'dry'
to test hyperbolic routing and compare with link state. Default is link-state.""")
parser.add_argument("--no-nlsr", action="store_false", dest="isNlsrEnabled",
help="Run mini-ndn without NLSR routing")
parser.add_argument("--list-experiments", action=PrintExperimentNames,
help="Lists the names of all available experiments")
parser.add_argument("--no-cli", action="store_false", dest="isCliEnabled",
help="Run experiments and exit without showing the command line interface")
parser.add_argument("--nPings", type=int, default=300,
help="Number of pings to perform between each node in the experiment")
# store_true stores default value of False
parser.add_argument("--nlsr-security", action="store_true", dest="nlsrSecurity",
help="Enables NLSR security")
parser.add_argument("-t", "--testbed", action="store_true", dest="testbed",
help="Instantiates a snapshot of the NDN Testbed irrespective of the tempfile provided")
parser.add_argument("--work-dir", action="store", dest="workDir", default="/tmp/minindn",
help="Specify the working directory; default is /tmp/minindn")
parser.add_argument("--result-dir", action="store", dest="resultDir", default=None,
help="Specify the full path destination folder where experiment results will be moved")
parser.add_argument("--pct-traffic", dest="pctTraffic", type=float, default=1.0,
help="Specify the percentage of nodes each node should ping")
parser.add_argument('--version', '-V', action='version', version='%(prog)s ' + VERSION_NUMBER,
help='Displays version information')
parser.add_argument("--cluster", metavar='localhost,server2,...',
help="Run cluster edition")
parser.add_argument("--placement", default='guided',
choices=['roundRobin', 'guided'])
parser.add_argument("--place-list", dest="placeList",
help="""Provide corresponding number of nodes (comma separated) to put on
each node respectively of --cluster when guided placement is used""")
parser.add_argument("--tunnel-type", dest="tunnelType", default='ssh',
choices=['ssh', 'gre'])
parser.add_argument("--face-type", dest='faceType', default='udp', choices=['udp', 'tcp'])
parser.add_argument("--cs-size", dest='csSize', type=int, default=65536,
help="Set CS size in NFD's conf file")
ExperimentManager.addExperimentArgs(parser)
if "argcomplete" in sys.modules:
argcomplete.autocomplete(parser)
args = parser.parse_args()
options = ProgramOptions()
options.templateFile = args.tempfile
options.ctime = args.ctime
options.experimentName = args.experiment
options.nFaces = args.faces
options.routingType = args.routingType
options.isNlsrEnabled = args.isNlsrEnabled
options.isCliEnabled = args.isCliEnabled
options.nlsrSecurity = args.nlsrSecurity
options.nPings = args.nPings
options.testbed = args.testbed
options.workDir = args.workDir
options.resultDir = args.resultDir
options.pctTraffic = args.pctTraffic
options.cluster = args.cluster
options.placement = args.placement
options.tunnelType = args.tunnelType
options.placeList = args.placeList
options.faceType = args.faceType
options.csSize = args.csSize
options.arguments = args
if options.experimentName is not None and options.experimentName not in ExperimentManager.getExperimentNames():
error("No experiment named {}\n".format(options.experimentName))
sys.exit(1)
if options.experimentName is not None and options.resultDir is None:
warn("No results folder specified; experiment results will remain in the working directory\n")
if options.cluster is not None:
servers = options.cluster.split(',')
for server in servers:
ClusterCleanup.add(server)
options.servers = servers
if options.placement == "roundRobin":
options.placement = RoundRobinPlacer
elif options.placement == "guided":
if options.placeList is None or not re.match("^[0-9,]+$", options.placeList):
error("Please specify correctly how many nodes you want to place on each node!")
sys.exit(1)
else:
try:
options.placeList = map(int, options.placeList.split(","))
except ValueError:
error("Please specify the nodes correctly, no comma at the beginning/end!")
sys.exit(1)
PopulatePlacement(options.placeList)
options.placement = GuidedPlacer
if options.tunnelType == "ssh":
options.tunnelType = RemoteNdnLink
else:
options.tunnelType = RemoteGRENdnLink
return options
class NdnTopo(Topo):
def __init__(self, conf_arq, workDir, **opts):
Topo.__init__(self, **opts)
self.hosts_conf = parse_hosts(conf_arq)
self.switches_conf = parse_switches(conf_arq)
self.links_conf = parse_links(conf_arq)
self.isTCLink = False
self.isLimited = False
for host in self.hosts_conf:
if host.cpu != None and self.isLimited != True:
self.isLimited = True
self.addHost(host.name, app=host.app, params=host.params, cpu=host.cpu,
cores=host.cores,cache=host.cache, workdir=workDir)
for switch in self.switches_conf:
self.addSwitch(switch.name)
for link in self.links_conf:
if len(link.linkDict) == 0:
self.addLink(link.h1, link.h2)
else:
self.addLink(link.h1, link.h2, **link.linkDict)
self.isTCLink = True
info('Parse of ' + conf_arq + ' done.\n')
def execute(options):
"Create a network based on template_file"
if options.testbed:
options.templateFile = INSTALL_DIR + 'minindn.testbed.conf'
if os.path.exists(options.templateFile) == False:
error('Template file cannot be found. Exiting...\n')
sys.exit(1)
if options.cluster is not None and options.placement == GuidedPlacer:
num_nodes = 0
with open(options.templateFile, 'r') as topo:
for line in topo:
if ': _' in line:
num_nodes += 1
if sum(options.placeList) != num_nodes:
error("Placement list sum is not equal to number of nodes!")
sys.exit(1)
# Copy nfd.conf to remote hosts - this assumes that NDN versions across
# the cluster are at least compatible if not the same
if options.cluster is not None:
for server in options.servers:
if server != "localhost":
login = "mininet@{}".format(server)
src = nfdConfFile
dst = "{}:/tmp/nfd.conf".format(login)
scp(src, dst)
ssh(login, "sudo cp /tmp/nfd.conf {}".format(src))
if options.resultDir is not None:
options.resultDir = createResultsDir(options.resultDir, options.nFaces, options.routingType)
topo = NdnTopo(options.templateFile, options.workDir)
if topo.isTCLink == True and topo.isLimited == True:
net = Mininet(topo,host=CpuLimitedNdnHost,link=TCLink)
elif topo.isTCLink == True and topo.isLimited == False:
if options.cluster is not None:
mn = partial(MininetCluster, servers=options.servers, placement=options.placement)
net = mn(topo=topo, host=RemoteNdnHost, link=options.tunnelType)
else:
net = Mininet(topo, host=NdnHost, link=TCLink)
elif topo.isTCLink == False and topo.isLimited == True:
net = Mininet(topo, host=CpuLimitedNdnHost)
else:
net = Mininet(topo, host=NdnHost)
net.start()
# Giving proper IPs to intf so neighbor nodes can communicate
# This is one way of giving connectivity, another way could be
# to insert a switch between each pair of neighbors
ndnNetBase = "1.0.0.0"
interfaces = []
for host in net.hosts:
for intf in host.intfList():
link = intf.link
node1, node2 = link.intf1.node, link.intf2.node
if node1 in net.switches or node2 in net.switches:
continue
if link.intf1 not in interfaces and link.intf2 not in interfaces:
interfaces.append(link.intf1)
interfaces.append(link.intf2)
node1.setIP(ipStr(ipParse(ndnNetBase) + 1) + '/30', intf=link.intf1)
node2.setIP(ipStr(ipParse(ndnNetBase) + 2) + '/30', intf=link.intf2)
ndnNetBase = ipStr(ipParse(ndnNetBase) + 4)
time.sleep(2)
info('Starting NFD on nodes\n')
for host in net.hosts:
host.nfd = Nfd(host, options.csSize)
host.nfd.start()
for host in net.hosts:
if 'app' in host.params:
if host.params['app'] != '':
app = host.params['app']
info("Starting {} on node {}".format(app, host.name))
info(host.cmd(app))
# Determine if each host is running NFD
for host in net.hosts:
nfdStatus = host.cmd("ps -g -U root | grep 'nfd --config {}/[n]fd.conf'".format(host.homeFolder))
if not host.nfd.isRunning or not nfdStatus:
error("NFD on host {} is not running. Printing log file and exiting...".format(host.name))
info(host.cmd("tail {}/nfd.log".format(host.homeFolder)))
net.stop()
sys.exit(1)
# Load experiment
experimentName = options.experimentName
experimentArgs = {
"net": net,
"options": options
}
if experimentName is not None:
info("Loading experiment: {}\n".format(experimentName))
experiment = ExperimentManager.create(experimentName, experimentArgs)
if experiment is not None:
experiment.start()
else:
error("Experiment '{}' does not exist\n".format(experimentName))
return
else:
experiment = Experiment(experimentArgs)
if options.isNlsrEnabled:
experiment.startNlsr(checkConvergence = False)
if options.isCliEnabled is True:
MiniNDNCLI(net)
net.stop()
if options.resultDir is not None:
info("Moving results to {}".format(options.resultDir))
for file in glob.glob('{}/*'.format(options.workDir)):
shutil.move(file, options.resultDir)
if options.cluster is not None:
for server in options.servers:
if server != "localhost":
login = "mininet@{}".format(server)
src = "{}:{}/*".format(login, options.workDir)
dst = options.resultDir
scp(src, dst)
info("Please clean work directories of other machines before running the cluster again")
def signal_handler(signal, frame):
info('Cleaning up...')
call(["nfd-stop"])
call(["sudo", "mn", "--clean"])
sys.exit(1)
def verify_dependencies():
"Prevent MiniNDN from running without necessary dependencies"
dependencies = ["nfd", "nlsr", "infoedit", "ndnping", "ndnpingserver"]
devnull = open("/dev/null", "w")
# Checks that each program is in the system path
for program in dependencies:
if call(["which", program], stdout=devnull):
error("{} is missing from the system path! Exiting...".format(program))
sys.exit(1)
devnull.close()
if __name__ == '__main__':
signal.signal(signal.SIGQUIT, signal_handler)
options = parse_args()
setLogLevel('info')
verify_dependencies()
try:
execute(options)
except Exception as e:
error("{}".format(e))
call(["nfd-stop"])
call(["sudo", "mn", "--clean"])
sys.exit(1)
-1901
View File
File diff suppressed because it is too large. Load diff
-25
View File
@@ -1,25 +0,0 @@
Mini-NDN cluster edition
========================
Mini-NDN cluster edition uses the experimental Mininet cluster edition.
**Make sure that you can run the Mininet cluster edition by following
[these instructions](https://github.com/mininet/mininet/wiki/Cluster-Edition-Prototype)**.
Mini-NDN will use the "mininet" username created in Mininet cluster edition setup.
## Mini-NDN cluster options
To run Mini-NDN cluster on `localhost` and another server `server1` with
the guided node placement strategy (default), the following command can be used:
sudo minindn --cluster=localhost,server1 --place-list=1,3
Note that `place-list` specifies the number of nodes to be placed on the corresponding servers
of the cluster.
In the example, one node will be placed on `localhost` and three nodes on `server1`.
Unless specified, the default 4 node topology is used.
Another placement can be `roundRobin` placement algorithm from Mininet.
This does not require a place-list.
sudo minindn --cluster=localhost,server1 --placement roundRobin
By default the tunnel type used is SSH, but GRE tunnel can be specified by `--tunnel-type=gre`
-68
View File
@@ -1,68 +0,0 @@
Configuration
=============
Mini-NDN uses a configuration file describing the topology and its parameters to setup a network.
It can be generated by the GUI or written by hand or scripts.
## Configuration file format:
### The [nodes] section:
At the bare minimum, the node section describes the nodes present in the topology.
[nodes]
a: _
b: _
Additionally each node can take the following parameters:
* app : Default application(s) to be started on a node (specify '_' if no app needs to be started - required).
The app is the only parameter which needs double quotes (see example below).
* cpu : Amount of cpu available to a node (0.00 - 1.00), optional
* mem : Amount of memory available to a node in KB
* cache : Amount of cache memory available to a node in KB
* nfd-log-level: Set the log level of the NFD running on the node (ex: DEBUG). For finer control,
nfd.conf or nfd.conf.sample needs to be modified in /usr/local/etc/ndn/
* nlsr-log-level: Set the log level of the NLSR running on the node (ex: DEBUG).
e.g.)
[nodes]
a: _ cpu=0.3 nfd-log-level=TRACE nlsr-log-level=NONE
b: app="sample app 1; sampleapp2.sh" cpu=0.3
### The [links] section:
The links section describes the links in the topology.
e.g.)
[links]
a:b delay=10ms
This would create a link between a and b. 'b:a' would also result in the same.
The following parameters can be configured for a node:
* delay : Delay parameter is a required parameter which defines the delay of the link (1-1000ms)
* bw : Bandwidth of a link (<1-1000> Mbps)
* loss : Percentage of packet loss (<1-100>)
### Example configuration file
[nodes]
a: _ cpu=0.3
b: app="sampleApp1; ./sampleApp2.sh" cpu=0.3
[links]
a:b delay=10ms bw=100
Note that `sampleApp1` and `sampleApp2` must be either installed in the system (ex: /usr/bin)
or an absolute path needs to be given.
See `topologies` for more sample files
-207
View File
@@ -1,207 +0,0 @@
Experiments
===========
Mini-NDN includes an experimentation framework which allows a user to create and automate
networking experiments. Users can run existing experiments, included with Mini-NDN, or define
their own custom experiment.
## Running existing experiments
Mini-NDN includes three example experiments that can be used to test the network or as reference
for custom experiment implementations. `ndn-tools` must be installed to run the example
experiments as each experiment uses both `ndnpingserver` and `ndnping`. Please see
[INSTALL.md](../INSTALL.md) for instructions on installing `ndn-tools`.
To see a list of the available experiments, run Mini-NDN using the `--list-experiments` parameter:
minindn --list-experiments
To run an experiment, provide the experiment name as an argument to the `--experiment` parameter:
sudo minindn --experiment=pingall
Each experiment will run until completion or exit if there is an error setting up the
test environment.
The three included experiments are set up using the same starting
configuration. Each node runs NFD, NLSR, and an ndnpingserver which advertises the node's
site name. After a waiting period to allow the network to converge (default is 60 seconds),
the convergence status of the network is checked. If each node's FIB does not have an entry
for every other node's router name and advertised prefix, the experiment is aborted and an error
is reported.
#### Common experiment parameters
The time allowed for convergence (in seconds) can be configured using the `--ctime` parameter:
sudo minindn --ctime=30 ...
After the experiment has finished running, the command-line interface (CLI) will be launched and the
user can then interact with the test environment. To disable the CLI and instead exit Mini-NDN
as soon as the experiment has finished, use the `--no-cli` parameter:
sudo minindn --no-cli ...
To ping only a percentage of nodes `--pct-traffic` can be set.
sudo minindn --pct-traffic=0.5 ...
The above command will ping only 50% of other nodes from each node.
The default value is 1 i.e. ping every other node.
To move the experiment results to a results directory from the working directory
after the experiment is complete (either --no-cli or quit) the following option
can be used:
sudo minindn --result-dir /home/mydir/result-dir ...
The included experiments are described in detail below along with additional
parameters that can be provided to modify the execution of the experiments.
### Pingall experiment
**Scenario**: Each node in the network simultaneously pings every other node in the network at a
one second interval.
**Experiment ID**: `--pingall`
The number of pings sent in the experiment can be configured using the `--nPings` parameter:
sudo minindn --experiment=pingall --nPings=120
By default, `--nPings` is 300 for the Pingall experiment.
### Failure experiment
**Scenario**: Each node in the network simultaneously pings every other node in the network at a
one second interval. After 60 seconds, the node with the name "csu" is brought down. The node is
left in a failed state for 120 seconds while the other nodes continue pinging. After this period,
the failed node is recovered and pings are collected for an additional 90 seconds.
**Experiment ID**: `--failure`
`--nPings` is 300 for the Failure experiment and cannot be modified.
### Multiple failure experiment
**Scenario**: Each node in the network simultaneously pings every other node in the network at a
one second interval. After 60 seconds, the first node in the network will be brought down and remain
in failed state for 60 seconds. After the failure period, the node is recovered and the network
is allowed to recover for 60 seconds. After the recovery period, the next node will go through this
failure and recovery process. Once every node in the network has gone through the failure and
recovery process, the experiment will end.
**Experiment ID**: `--multiple-failure`
`--nPings` is dependent on the size of the topology being tested. 120 pings are scheduled for
each node's failure/recovery period as well as an additional 60 pings for the initial collection
period.
### MCN failure experiment
**Scenario**: This is exactly like the failure experiment but instead of failing the node named "csu" it fails the most connected node (MCN) i.e the node with the most links.
Experiment ID: `--mcn-failure`
### Experiment data
The ping data is stored at `/tmp/minindn/node-name/ping-data`.
The ping server log is stored at `/tmp/minindn/node-name/ping-server`
## Creating custom experiments
Mini-NDN provides a simple Python based framework which allows a user to define their own experiment
and run it from the command line.
To create an experiment, follow these steps:
1. Create a Python source file for the experiment in the `ndn/experiments` directory.
e.g.) `ndn/experiments/example.py`
2. Derive the experiment from the `Experiment` base class defined in
`ndn/experiments/experiment.py`.
#!/usr/bin/python
from ndn.experiments.experiment import Experiment
class ExampleExperiment(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
3. Override `start()` if the experiments want to override NLSR setup and skip `setup()` and `run()`
as described below. `start()` is the entry point for an experiment.
4. Override the `setup()` method to define how the experiment should be initialized
e.g.) Run an ndnping server in the background on each node
def setup(self):
for host in self.net.hosts:
host.cmd("ndnpingserver host.name &")
5. Override the `run()` method to define how the experiment should behave
e.g.) Obtain the NFD status of each node and save it to file
def run(self):
for host in self.net.hosts:
host.cmd("nfdc status report > status.txt")
6. Register the experiment with the `ExperimentManager` to make the experiment runnable from the
command line.
Experiment.register("example-name", ExampleExperiment)
The experiment can then be run from the command-line using the name registered.
"example-name" in the above example:
sudo minindn --experiment=example-name
### Full example experiment code
#!/usr/bin/python
from ndn.experiments.experiment import Experiment
class ExampleExperiment(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
def setup(self):
for host in self.net.hosts:
host.cmd("ndnpingserver host.name &")
def run(self):
for host in self.net.hosts:
# By default status.txt would be stored
# at /tmp/minindn/host/status.txt
host.cmd("nfdc status report > status.txt")
Experiment.register("example-name", ExampleExperiment)
## Passing arguments to experiments
Mini-NDN has the capacity to pass arguments to experiments, insofar
as they do not clash with those of Mini-NDN. This feature
allows users to pass arguments to Mini-NDN and process them in an
experiment without having to rewrite Mini-NDN's core.
An example of an experiment implementing this functionality is given in
`ndn/experiments/arguments_experiment.py`, which demonstrates how to
write code which handles arguments. Documentation for these arguments
appears when called with `sudo minindn -h`, as does documentation for
fixed arguments defined in core code, so it is strongly recommended to
differentiate those you write yourself. Note that Bash and Zsh users
can make use of autocomplete functionality when calling these arguments.
To run the experiment:
sudo minindn --experiment arg-exp --ds 226 --logging
The experiment will print out the supplied value for --ds and a boolean
value for the presence of --logging. --experiment is a fixed argument of
Mini-NDN.
-115
View File
@@ -1,115 +0,0 @@
Getting Started
===============
## Installation
Please see [INSTALL.md](../INSTALL.md) for instructions on installing Mini-NDN and its dependencies.
## Running Mini-NDN
To run Mini-NDN with the default topology, `ndn_utils/topologies/default-topology.conf`, type:
sudo minindn
A full list of options can be printed by using:
sudo minindn --help
To run Mini-NDN with a topology file, provide the filename as the first argument:
sudo minindn my-topology.conf
During set up, the list of nodes in the network will be listed as they are initialized:
*** Adding hosts:
a b c d
After set up, the command-line interface (CLI) will display a prompt.
mini-ndn>
To interact with a node, first type the node's name and then the command to be executed:
mini-ndn> a echo "Hello, world!"
Hello, world!
To see the status of the forwarder on the node:
mini-ndn> a nfdc status report
To see the status of routing on the node:
mini-ndn> a nlsrc status
To exit Mini-NDN, type `quit` in the CLI:
mini-ndn> quit
Another option to quit Mini-NDN is sending a SIGQUIT (ctrl+\). SIGINT (ctrl+c)
is reserved for the purpose of stopping applications initiated on the minindn command
line.
For a more in depth explanation of the CLI, please see the
[Mininet Walkthrough](http://mininet.org/walkthrough/).
## Command-line options
To run Mini-NDN with a replica of the NDN testbed, use the `--testbed` parameter:
sudo minindn --testbed
To change the working directory from default `/tmp/minindn` following option can be used:
sudo minindn --work-dir /home/mydir/test
Autocomplete of command-line options is available for users of Bash and Zsh.
#### Routing options
To run minindn without NLSR, use the `--no-nlsr` parameter:
sudo minindn --no-nlsr
To run NLSR with hyperbolic routing enabled, use the `--routing` parameter:
sudo minindn --routing hr
Topology files given under ndn_utils/topologies/minindn* have hyperbolic coordinates configured
and can be used with this option.
To run NLSR in dry-run mode, use the `--routing` parameter:
sudo minindn --routing dry
To configure the max number of faces added by NLSR to reach each name prefix, use the `--faces`
parameter:
sudo minindn --faces 3
`--faces` can be an integer from 0 to 60; 0 indicates NLSR can add all available faces.
To run Mini-NDN with NLSR security configured
sudo minindn --nlsr-security
## Working Directory Structure
Currently Mini-NDN uses /tmp/minindn as the working directory if not specified otherwise by using
the option --work-dir.
Each node is given a HOME directory under /tmp/minindn/node-name
where node-name is the name of the node specified in the [nodes] section of the conf file.
### NFD
NFD conf file is stored at `/tmp/minindn/node-name/node-name.conf`
NFD log file is stored at `/tmp/minindn/node-name/node-name.log`
`.ndn` folder is stored at `/tmp/minindn/node-name/.ndn`
### NLSR
NLSR conf file is stored at `/tmp/minindn/node-name/nlsr.conf`
NLSR log file is stored at `/tmp/minindn/node-name/log/nlsr.log`
When security is enabled, NLSR security certificates are stored in: `/tmp/minindn/node-name/security`
Note that no NLSR publishes the root certificate, Mini-NDN installs root.cert in security folder for each NLSR.
-81
View File
@@ -1,81 +0,0 @@
Mini-NDN Edit
=============
Mini-NDN Edit is a GUI program designed to simplify the creation of Mini-NDN topology
configuration files. Mini-NDN Edit allows the user to build a topology, configure the hosts and
links, and generate a topology file that can be used by Mini-NDN.
![minindnedit](img/gui/minindnedit.png)
## Working with topology files
#### File formats
There are two file formats used by Mini-NDN edit.
* `.mnndn` files store topology information used by the GUI. Mini-NDN Edit can open and
save `.mnndn` files.
* `.conf` files are used by Mini-NDN to create and run topologies. Mini-NDN Edit can generate a
`.conf` file from a `.mnndn` file. Mini-NDN edit cannot open `.conf` files. Please see
[CONFIG-FILE.md](CONFIG.md) for more information on the content and format of `.conf` files.
#### File menu
![file-dropdown](img/gui/file-dropdown.png)
* **New** - Erase the current canvas and provide a new empty topology
* **Open** - Open a `.mnndn` topology file
* **Save** - Save the current topology as a `.mnndn` topology file
* **Generate** - Convert the current topology to a `.conf` file runnable by Mini-NDN
* **Run** - Run the current topology in Mini-NDN. The GUI will disappear and Mini-NDN will run on
the command-line.
* **Quit** - Exit Mini-NDN edit
## Tools
### Cursor tool
![cursor-tool](img/gui/cursor-tool.png)
The *cursor tool* is used to select and move nodes in the topology. A selected node or link can be
removed from the topology using the `backspace` key or by selecting `edit/cut`.
### Host tool
![host-tool](img/gui/host-tool.png)
The *host tool* is used to add a host node to the topology. Click on the canvas to create a new host
node at the mouse cursor's position.
### Switch tool
![switch-tool](img/gui/switch-tool.png)
The *switch tool* is used to add a switch to the topology. Click on the canvas to create a new
switch at the mouse cursor's position.
### Link tool
![link-tool](img/gui/link-tool.png)
The *link tool* is used to connect two nodes with a network link. Click on a node and drag the mouse
cursor to another node to create a link between the two nodes.
## Configuration
#### Editing host information
To edit a host's information and configuration, right-click on the desired node and select
`Host Options`.
The *Host Options* window will include tabs to modify the node's properties as well as the
configuration files for NFD and NLSR on that node.
*Note: Network, Site, and Router in the NLSR tab are unused in v0.1.0*
![host-config](img/gui/host-config.png)
#### Editing link configuration
To edit a link's configuration, right-click on the desired link and select `Link Options`.
The *Link Options* window will allow configuration of the link's bandwidth, delay, and loss rate.
![link-details](img/gui/link-details.png)
+20
View File
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-176
View File
@@ -1,176 +0,0 @@
Release Notes
=============
Mini-NDN version 0.4.0 (changes since version 0.3.0)
----------------------------------------------------
Release date: January 10, 2018
**New features**:
- Use SIGQUIT to quit Mini-NDN, SIGINT to kill programs
- Use Infoedit to edit NFD and NLSR configuration files
- Use nlsr.conf installed in the system
- Provide a Vagrantfile to setup Mini-NDN and NDN
- Provide option to disable NLSR
- Provide an option to run NLSR in dry-run mode
- Add option to specify whether to use TCP or UDP face in nlsr.conf
- Add option to specify arbitrary arguments to use in experiments
- Include a single option to install Mini-NDN and all the dependencies
**Bug fixes**:
- Fix "key does not exist error" after NLSR starts
- Update install.sh to call ldconfig after installing ChronoSync
- Add hyperbolic coordinates to default topology
**Misc changes**:
- Add an experiment to test nlsrc
- Create faces in NFD for each neighbor in NLSR
- Update to latest ndn-cxx
- Use /tmp/minindn folder as default work dir instead of /tmp
Mini-NDN version 0.3.0 (changes since version 0.2.0)
----------------------------------------------------
Release date: March 3, 2017
**New features**:
- Mini-NDN cluster edition
- New experiments for making NLSR testing easier
**Bug fixes**:
- Set site name correctly
- Install missing certificates in NLSR security config
- Fix quitting of NLSR due to key not found error
**Misc changes**:
- Removed nlsr.conf file, generate it within the code
- Use argparse instead of deprecated optparse
- Update security config section for NLSR
- Change mininet prompt to mini-ndn
- Set network name at one place
- Update install.sh script to install openssl
- Update install.sh script to install cryptopp from package instead of compiling from source
- Update install.sh to clean build folder every time to get rid of removed files such as old experiments
- Fix old code - use net.hosts instead of storing hosts in a variable
- Use nfdc instead of deprecated nfd-status
Mini-NDN version 0.2.0 (changes since version 0.1.1)
----------------------------------------
Release date: August 18, 2016
**New features**:
- Automatic security configuration for NLSR
- Use /usr/local/etc/ndn/nfd.conf as default config file for NFD
- Class to monitor /proc/$PID/stat file for PID
- Mini-NDN exits gracefully on SIGINT and non-convergence
- Faster Mini-NDN install script - does not do apt-get update everytime
- NLSR is launched with explicit config file for easier process identification
- Add and update more documentation
**Bug fixes**:
- NFD is killed correctly on exit
- Best route strategy is set correctly
Mini-NDN version 0.1.1 (changes since version 0.1.0)
----------------------------------------
Release date: November 4, 2015
**New features**:
- Use nfd.conf.sample from currently installed NFD
- Add working directory option to allow execution environment outside of /tmp
- Add results directory option to store experiment results after completion
- Add support for switches in GUI and configuration file
- Add failNode and recoverNode methods to Experiment class
- Add most connected node (MCN) failure experiment
- Add option to specify percentage of nodes pinged
**Code changes**:
- Refactor program options into container class
- Remove unused "FIB Entries" option from NDN host options
**Bug fixes**:
- Abort start up if experiment name is invalid
- Restart pings after recovery in failure experiment
Mini-NDN version 0.1.0 (initial release)
----------------------------------------
Release date: July 15, 2015
Mini-NDN is a lightweight networking emulation tool that enables testing, experimentation, and
research on the NDN platform. Based on Mininet, Mini-NDN uses the NDN libraries, NFD, NLSR, and
tools released by the [NDN project](http://named-data.net/codebase/platform/) to emulate
an NDN network on a single system.
**Included features**:
- Run a complete NDN network on a single system
- Automatic configuration of NLSR to provide a routable NDN network
- Supports user created NDN applications
- Create a topology using the included Mini-NDN Edit GUI application
- Allows individual configuration of NFD and NLSR parameters for each node
- Provides an experiment management framework for easy creation of custom networking experiments
- Uses a simple topology file format to define hosts, links, and configuration values
- Configure network link parameters including bandwidth, delay, and loss rate
- Includes a pre-configured topology file to replicate the NDN testbed
+56
View File
@@ -0,0 +1,56 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
from datetime import datetime
from minindn import __version__
# -- Project information -----------------------------------------------------
project = 'Mini-NDN'
copyright = '2015-{}, Mini-NDN. This research is partially supported by NSF.'.format(datetime.now().year)
author = 'Mini-NDN'
# The full version, including alpha/beta/rc tags
release = __version__
version = __version__
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
+235
View File
@@ -0,0 +1,235 @@
Experiment
==========
Configuration
-------------
Mini-NDN uses a configuration file describing the topology and its parameters to setup a network.
The [nodes] section:
At the bare minimum, the node section describes the nodes present in the
topology.
::
[nodes]
a: key1=value1 key2=value2
b: key1=value1
Any key and value passed here is accessible in Mini-NDN as:
::
ndn = Minindn(...)
value = ndn.net.hosts[0].params['params'].get('key1', "defaultValue")
One can specify log levels for each node's NFD and NLSR using this key-value system:
::
[nodes]
a: nfd-log-level=DEBUG nlsr-log-level=DEBUG
b: nfd-log-level=INFO
To specify a log level for certain modules of NFD, the following line can be added to `nfd.py`:
::
node.cmd('infoedit -f {} -s log.Forwarder -v {}'.format(self.confFile, 'INFO'))
This will turn on FORWARDER logging to INFO for all nodes.
.. Todo: Add switch section
The [links] section:
The links section describes the links in the topology.
::
e.g.)
[links]
a:b delay=10ms
This would create a link between a and b. 'b:a' would also result in the
same. The following parameters can be configured for a node:
- delay : Delay parameter is a required parameter which defines the
delay of the link (1-1000ms)
- bw : Bandwidth of a link (<1-1000> Mbps)
- loss : Percentage of packet loss (<1-100>)
Example configuration file
::
[nodes]
a:
b:
[links]
a:b delay=10ms bw=100
See ``ndn_utils/topologies`` for more sample files
Sample
------
Sample experiment may written as follows:
.. code:: python
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.appmanager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.routing_helper import IPRoutingHelper
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
# Can pass a custom parser, custom topology, or any Mininet params here
ndn = Minindn()
ndn.start()
# IP reachability if needed
# IPRoutingHelper.calcAllRoutes(ndn.net)
# info("IP routes configured, start ping\n")
# ndn.net.pingAll()
# Start apps with AppManager which registers a clean up function with ndn
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Starting NLSR on nodes\n')
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
# or can not start NLSRs with some delay in between:
# nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
# for host in ndn.net.hosts:
# nlsrs.startOnNode(host)
# time.sleep(30)
MiniNDNCLI(ndn.net)
# Calls the clean up functions registered via AppManager
ndn.stop()
Users may look at how the NFD and NLSR applications are written as a sub class of Application
in the ``minindn/apps`` folder. Or users may choose to directly run their application on nodes
such as ndnpingserver is run in ``minindn/helpers/experiment.py``.
Execution
---------
To run Mini-NDN with the default topology,
``ndn_utils/topologies/default-topology.conf``, type:
::
sudo python examples/minindn.py
To run Mini-NDN with a topology file, provide the filename as the first
argument:
::
sudo python examples/minindn.py my-topology.conf
After Mini-NDN is installed, users can run examples from anywhere with python directly as follows:
::
sudo python /path/to/myexample.py
The user no longer needs to create an experiment in the old Mini-NDN way, then install it to the system before executing it via the minindn binary. The new examples can be separate from the Mini-NDN folder if the core is not being modified.
CLI Interface
_____________
During set up, the list of nodes in the network will be listed as they
are initialized:
::
*** Adding hosts:
a b c d
After set up, the command-line interface (CLI) will display a prompt.
::
mini-ndn>
To interact with a node, first type the node's name and then the command
to be executed:
::
mini-ndn> a echo "Hello, world!"
Hello, world!
To see the status of the forwarder on the node:
::
mini-ndn> a nfdc status report
To see the status of routing on the node:
::
mini-ndn> a nlsrc status
To exit Mini-NDN, type ``quit`` in the CLI or use ``ctrl + D``:
::
mini-ndn> quit
``Ctrl + C`` is used to quit an application run in the foreground of the command line.
For a more in depth explanation of the CLI, please see the `Mininet
Walkthrough <http://mininet.org/walkthrough/>`__.
To run NDN commands from the outside the command line user can also open a new terminal
and export the HOME folder of a node ``export HOME=/tmp/minindn/a && cd ~``
Working Directory Structure
---------------------------
Currently Mini-NDN uses /tmp/minindn as the working directory if not
specified otherwise by using the option --work-dir.
Each node is given a HOME directory under /tmp/minindn/<node-name> where
<node-name> is the name of the node specified in the [nodes] section of
the conf file.
NFD
___
- NFD conf file is stored at ``/tmp/minindn/<node-name>/nfd.conf``
- NFD log file is stored at ``/tmp/minindn/<node-name>/log/nfd.log``
- ``.ndn`` folder is stored at ``/tmp/minindn/<node-name>/.ndn``
NLSR
____
- NLSR conf file is stored at ``/tmp/minindn/<node-name>/nlsr.conf``
- NLSR log file is stored at ``/tmp/minindn/<node-name>/log/nlsr.log``
When security is enabled, NLSR security certificates are stored in:
``/tmp/minindn/<node-name>/security`` Note that no NLSR publishes the root
certificate, Mini-NDN installs root.cert in security folder for each
NLSR.
+48
View File
@@ -0,0 +1,48 @@
FAQ
=========
* ``How does Mini-NDN work?``
Mini-NDN's principles of operation most heavily rely on the underlying Mininet code it relies on.
Mininet uses a combination of limited containerization via network namespaces (which give processes
isolated interfaces and routing tables) and emulated ethernet connections via veth connections.
In practical terms, Mini-NDN ensures that processes running on distinct nodes will run seperately
and without interfering with each other.
* ``How does Mini-NDN apply link loss/delay/etc.?``
Mini-NDN relies on Mininet's code, which in turn uses the Linux tc utility on a stations' virtualized
interfaces to apply configurations known as qdiscs to these links. Note that these will only be applied
on egress packets from a station where it's applied.
For more information on qdiscs and tc, view the information `here <http://wiki.linuxwall.info/doku.php/en%3aressources%3adossiers%3anetworking%3atraffic_control>`_.
* ``Why use Mini-NDN rather than a simulator such as ndnSIM?``
Mini-NDN is easier and faster to use because, rather than serving as a mathematical model of a network,
it is instead running real NDN code on a real Linux kernel. This also means it's quite useful for testing code changes, as it can more accurately test the interaction of software componenents.
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Criteria | Mini-NDN | ndnSIM |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Based On | Mininet | ns-3 |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Language | Python | C++ |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Library/Forwarder/Applications | Use system binaries (free to use any compatible versions) | Integrated (fixed release version) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Application language | C++ (ndn-cxx), CCL (ndn-cpp, PyNDN, ndn-js, jNDN) | C++ (ndn-cxx) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Simulation size | Medium - Large (cluster edition in development) | Large (can be parallelized using MPI) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Simulation time | Real time | Quick (depending on size/memory) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Porting real applications | Drop in | Changes required |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Interactivity | Can interact directly with NFD, NLSR or Apps | Can show stats while running |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Logs | May need to manually setup to collect | Available with tracer |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Post processing scripts | Not available, users need to write their own | Available to use to process the logs |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Other | Not yet supported (Wifi in development) | WiFi, LTE, etc available from ns-3 |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
+9
View File
@@ -0,0 +1,9 @@
Past NDN Hackathon projects
===========================
- 1st NDN Hackathon: `NFD integration test <http://ndncomm.github.io/mini-ndn/>`_.
- 2st NDN Hackathon: `Mini-NDN metrics <https://github.com/2nd-ndn-hackathon/mini-ndn-metrics>`_.
- 3rd NDN Hackathon: `Mini-NDN cluster <https://github.com/3rd-ndn-hackathon/mini-NDN-cluster>`_.
- 4th NDN Hackathon: `Mini-NDN wifi <https://github.com/4th-ndn-hackathon/Mini-NDN-Wi-Fi>`_.
- 7th NDN Hackathon: `Mini-NDN documentation <https://github.com/7th-ndn-hackathon/mini-ndn-documentation>`_.
+58 -34
View File
@@ -1,40 +1,45 @@
Connect Mini-NDN nodes to an outside network
============================================
Howtos
======
Mini-NDN nodes can be connected to an outside network indirectly by running NFD on the local machine:
Connect Mini-NDN nodes to an outside network
---------------------------------------------
Mini-NDN nodes can be connected to an outside network indirectly by
running NFD on the local machine:
::
(Mini-NDN node) ------ (NFD running on the host machine where Mini-NDN is running) ------- (External Network)
## Add a node in root namespace
Add a node in root namespace
____________________________
For this simple example, we use the default topology:
For this simple example, we can use a single node topology with node 'a'
c----a----b----d
If we want node 'a' to connect to the host machine, we need to add a
"root" node which has a link with node "a."
If we want node "a" to connect to the host machine, we need to add a "root" node which has a link with node "a."
Then the following code can be used:
To do so, we need to add the following import statement at the top of `bin/minindn`:
.. code:: python
```python
from mininet.node import Node
```
topo = Topo()
root = topo.addHost('root', inNamespace=False)
a = topo.addHost('a')
topo.addLink(root, a, delay='10ms')
Then the following lines can be added to `bin/minindn` before net.start():
ndn = Minindn(topo=topo)
```python
root = Node( 'root', inNamespace=False )
net.addLink(root, 'a')
```
...
Adding these before net.start() is important as node "root" would then be assigned an IP automatically.
Re-install Mini-NDN by issuing the following command in the mini-ndn folder:
Configuration
_____________
sudo ./install.sh -i
Run Mini-NDN with the above code and issue ifconfig on the local
machine to confirm the addition of the interface. You should be able to
locate "root-eth0":
## Configuration
Run Mini-NDN with the simple topology and issue ifconfig on the local machine to confirm the addition of
the interface. You should be able to locate "root-eth0":
::
root-eth0 Link encap:Ethernet HWaddr 3e:eb:77:d2:6f:1f
inet addr:1.0.0.9 Bcast:1.0.0.11 Mask:255.255.255.252
@@ -45,25 +50,36 @@ the interface. You should be able to locate "root-eth0":
collisions:0 txqueuelen:1000
RX bytes:2667 (2.6 KB) TX bytes:2797 (2.7 KB)
To make the IP address associated with this interface persistent, add the following line to
/etc/network/interfaces and reboot your machine:
To make the IP address associated with this interface persistent, add
the following line to /etc/network/interfaces and reboot your machine:
::
iface root-eth0 inet manual
## Check connection
Check connection
________________
After rebooting, run Mini-NDN and issue the following command:
::
mini-ndn>net
a a-eth0:b-eth0 a-eth1:c-eth0 a-eth2:root-eth0
Node "a" is connected to "root-eth0". Now issue "ifconfig a-eth2" on node "a":
Node "a" is connected to "root-eth0". Now issue "ifconfig a-eth2" on
node "a":
::
mini-ndn>a ifconfig a-eth2
a-eth2 Link encap:Ethernet HWaddr fa:76:d4:86:d3:ba
inet addr:1.0.0.10 Bcast:1.0.0.11 Mask:255.255.255.252
As learned from the previous step, the IP address of root-eth0 is 1.0.0.9.
As learned from the previous step, the IP address of root-eth0 is
1.0.0.9.
::
mini-ndn>a ping 1.0.0.9
PING 1.0.0.9 (1.0.0.9) 56(84) bytes of data.
@@ -72,20 +88,28 @@ As learned from the previous step, the IP address of root-eth0 is 1.0.0.9.
The host machine will also be able to ping node "a":
::
VirtualBox:~$ ping 1.0.0.10
PING 1.0.0.10 (1.0.0.10) 56(84) bytes of data.
64 bytes from 1.0.0.10: icmp_seq=1 ttl=64 time=0.086 ms
## Run NFD on local machine and register route
Run NFD on local machine and register route
___________________________________________
Start NFD on the local machine by using:
::
sudo nfd
The "nfd-start" script cannot be used, since the script allows only one instance of NFD at a time.
The NFD processes running on the Mini-NDN nodes will prevent the "nfd-start" script from working.
The "nfd-start" script cannot be used, since the script allows only one
instance of NFD at a time. The NFD processes running on the Mini-NDN
nodes will prevent the "nfd-start" script from working.
Now, using "nfdc register", we can register a route from node "a" in Mini-NDN to the NFD process on the
host machine and from the host machine to an external machine.
Now, using "nfdc register", we can register a route from node "a" in
Mini-NDN to the NFD process on the host machine and from the host
machine to an external machine.
Also, if the local machine has a public IP, Mini-NDN nodes can be reached via external machines.
Also, if the local machine has a public IP, Mini-NDN nodes can be
reached via external machines.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

+29
View File
@@ -0,0 +1,29 @@
.. Mini-NDN documentation master file, created by
sphinx-quickstart on Mon Sep 23 11:15:54 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Mini-NDN: A Mininet-based NDN emulator
======================================
.. toctree::
:maxdepth: 2
:caption: Contents
introduction
install
experiment
howtos
release-notes
faq
hackathon
videos
Helpful Links
-------------
* `NDN Website <http://named-data.net/>`_
* `NDN Contributor's Guide <https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md>`_
* `Mininet Documentation <http://mininet.org/>`_
* `Mini-NDN redmine <https://redmine.named-data.net/projects/mini-ndn>`_
* `Mailing list <http://www.lists.cs.ucla.edu/mailman/listinfo/mini-ndn>`_
+174
View File
@@ -0,0 +1,174 @@
Install
=======
Prerequisites
-------------
For this guide, you will need a laptop/desktop with a recent version of
a Linux distro that is supported by Mininet. For this guide, the *Ubuntu 18.04 LTS* release was used.
Some tweaks maybe required to Mini-NDN's install.sh file for other distros.
Note that you'll need administrative privileges in order to download and install
extra packages and also to execute **Mini-NDN**.
Using Vagrantfile
-----------------
With Vagrant installed, simply do ``vagrant up`` which will bring up an Ubuntu 18.04 virtual machine
and install Mini-NDN and all its dependencies on it. Please make sure to tweak the CPU core count
(default 4 cores) and RAM (default 4GB) according to your needs before doing vagrant up. Mini-NDN
can be found in /home/vagrant/mini-ndn which is a symlink to /vagrant if Vagrantfile was used from within mini-ndn cloned on the host. Otherwise it is an actual clone of mini-ndn.
Using install.sh
----------------
Mini-NDN depends on Mininet and NDN software to be installed in the system.
If you have all the dependencies (see sections below) **installed in the system** simply
clone this repository and run:
::
./install.sh -i
The ``-i`` option uses ``setup.py develop`` to point the system install
to the current directory. So any changes made to the cloned ``mini-ndn``
folder will be used without having to install it again to the system.
If you do not need to modify the core of Mini-NDN, then setup.py install (or pip install .)
can be used directly. See :doc:`experiment <experiment>` for more information on running.
If you don't have the dependencies, the following command will
install them from source along with Mini-NDN. The dependencies include
Mininet, NDN core (ndn-cxx, NFD, Chronosync, PSync, NLSR), Infoedit,
and NDN Common Client Libraries (CCL). If you do not wish to install
the master versions of the NDN core or want to switch to specific versions,
you can edit the install.sh with release tags/specific versions.
.. _scaling-note:
.. important::
If you wish to scale Mini-NDN experiments and do not have use for security extensions
in your emulations, you should apply the ndn-cxx patch given in the ``patches`` folder
using ``./install.sh -p`` before running the following commands. The ndn-cxx patch is
taken from ndnSIM which provides an in-memory dummy KeyChain to reduce CPU computations.
After these patches are applied sleep time after NFD, nfdc, NLSR, etc. is not required
making the startup **MUCH** faster and scaling of Mini-NDN **MUCH** better.
::
./install.sh -a
This pulls the NDN software from Github to ``ndn-src`` folder under the project.
.. note::
If any changes are made to ``ndn-src`` folder, please don't forgot to re-install
the sources to the system.
To install without CCL, use:
::
./install.sh -mni
See ``install.sh -h`` for detailed options.
Installing Dependencies
-----------------------
Mininet
_______
Mini-NDN is based on Mininet. To install Mininet:
::
git clone --depth 1 https://github.com/mininet/mininet.git
After Mininet source is on your system, run the following command to
install Mininet core dependencies and Open vSwitch:
::
./util/install.sh -nv
To check if Mininet is working correctly, run this test:
::
sudo mn --test pingall
This will print out a series of statements that show the test setup and
the results of the test. Look for ``Results:`` two-thirds of the way
down where it will indicate the percentage of dropped packets. Your
results should show "0% dropped (2/2 received)".
NOTE: Mini-NDN, while providing a high level of emulation of hosts,
requires programs to be installed onto your computer. It will not work
if they are not installed. If you do not want NDN software installed
onto your computer, you can use a virtual machine, which can be quite
simply set up with the provided Vagrantfile.
NDN dependencies
________________
Each node in Mini-NDN will run the official implementation of NDN
installed on your system. The following dependencies are needed:
Mini-NDN uses NFD, NLSR, and ndn-tools.
- To install NFD: https://named-data.net/doc/NFD/current/INSTALL.html
- To install NLSR: https://named-data.net/doc/NLSR/current/INSTALL.html
- To install ndn-tools: https://github.com/named-data/ndn-tools
.. warning::
Please do not try to install NDN software from both the source (GitHub) and PPA (apt).
It will not work in most cases! If you used ./install.sh -a in the past but now want
to use apt, please run ``sudo ./waf uninstall`` in all the NDN projects before proceeding
with apt. Similarly, remove from apt if switching to source.
Please see the :ref:`scaling-note <scaling-note>` to learn about disabling
security for better scalability.
Note that all three of these can be installed from the Named Data PPA.
Instructions for setting it up can be found in the NFD installation
instructions. Note that PPA and installs from source **cannot** be
mixed. You must completely remove PPA installs from the system if switching
to source and vice-versa.
For PPA installs, if you are using a custom nfd.conf file in an experiment, you should
place it in /usr/local/etc/ndn/ rather than /etc/ndn/. This is to avoid
a bug from the default configuration file for the PPA, which is
incompatible with Mini-NDN.
Infoedit
________
Infoedit is used to edit configuration files for NFD and NLSR.
To install infoedit:
::
git clone --depth 1 https://github.com/NDN-Routing/infoedit
cd infoedit
make
sudo make install
Verification
------------
You can execute the following example to bring up the Mini-NDN command line
with NFD and NLSR running on each node:
::
sudo python examples/mnndn.py
You can use these steps to run the sample pingall experiment:
1. Issue the command: ``sudo python examples/nlsr/pingall.py``
2. When the ``mini-ndn>`` CLI prompt appears, the experiment has
finished. On the Mini-NDN CLI, issue the command ``exit`` to exit the
experiment.
3. Issue the command:
``grep -c content /tmp/minindn/*/ping-data/*.txt``. Each file should
report a count of 50.
4. Issue the command:
``grep -c timeout /tmp/minindn/*/ping-data/*.txt``. Each file should
report a count of 0.
+40
View File
@@ -0,0 +1,40 @@
Introduction
=================
If you are new to the NDN community of software generally, read the
`Contributor's Guide <https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md>`_.
What is Mini-NDN?
-----------------
Mini-NDN is a lightweight networking emulation tool that enables testing, experimentation, and
research on the NDN platform. It was initially based on `Mini-CCNx <https://github.com/chesteve/mn-ccnx>`_ which was a fork of `Mininet <https://github.com/mininet/mininet>`_. Mini-NDN uses the NDN libraries, NFD, NLSR, and tools released by the `NDN project <http://named-data.net/codebase/platform/>`_ to emulate an NDN network on a single system.
The first release of Mini-NDN is developed by members of the NSF-sponsored NDN project team.
Mini-NDN is open to contribution from the public.
.. image:: minindnnet.svg
License
_______
Mini-NDN is open and free software licensed under the GPL 3.0 license. Mini-NDN is free to all
users and developers. For more information about licensing details and limitations,
please refer to COPYING.md.
Feedback/Mailing List
_____________________
Bug reports and feedback are highly appreciated and can be made through our
`Redmine site <http://redmine.named-data.net/projects/mini-ndn>`_ and the
`mini-ndn mailing list <http://www.lists.cs.ucla.edu/mailman/listinfo/mini-ndn>`_.
Video
_____
.. raw:: html
<div id="video-container" class="col-md-6 ">
<p>Mini-NDN (content maybe outdated)</p>
<iframe width="600" height="345" src="https://www.youtube.com/embed/UxHPqaUwefg" frameborder="0" allowfullscreen=""></iframe>
</div>
+126
View File
@@ -0,0 +1,126 @@
<svg width="692" height="380" xmlns="http://www.w3.org/2000/svg">
<metadata id="metadata7">image/svg+xml</metadata>
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="382" width="694" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<g stroke="null" id="g3790">
<rect stroke="#000000" fill="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" id="rect2985" width="680.84682" height="350.443392" x="4.962804" y="5.773119" rx="0.324652"/>
<path stroke="#000000" fill="none" stroke-miterlimit="4" d="m4,175.828501l681.727736,1.357954" id="path3770"/>
</g>
<rect stroke="#000000" fill="#e3dedb" stroke-width="0.99538" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" rx="2.988095" y="176.111777" x="5.140841" height="180.524655" width="680.312936" id="rect3813"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="1.602133" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dasharray="4.80639973, 4.80639973" stroke-dashoffset="0" ry="8.582684" rx="7.476771" y="44.78072" x="55.492192" height="195.219243" width="148.366914" id="rect3764"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="1.638042" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dasharray="4.9141253, 4.9141253" stroke-dashoffset="0" id="rect3772" width="155.115252" height="195.190135" x="270.220868" y="46.153231" rx="7.816845" ry="8.581405"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="1.602133" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dasharray="4.80639973, 4.80639973" stroke-dashoffset="0" ry="8.582684" rx="7.476771" y="45.459696" x="489.86568" height="195.219243" width="148.366914" id="rect3774"/>
<text transform="matrix(1.0192718802397343,0,0,0.9115536073383187,-2.8313337784806336,-12.183034089773187) " font-size="16.005802px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3776" y="392.709737" x="551.171304" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="398.194877" x="552.152396" id="tspan3778">Kernel Space</tspan>
</text>
<text transform="matrix(1.0524848569125234,0,0,0.8827879284304422,-52.30106698198968,-77.5201889102731) " font-size="14.180006px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="601.466013" y="108.524983" id="text3782">
<tspan stroke="null" font-weight="normal" id="tspan3784" x="602.416145" y="114.188857">User Space</tspan>
</text>
<path stroke="#000000" fill="none" stroke-width="1px" id="path3796" d="m488.56554,176.773764c1.782236,0.480113 1.527628,0.360085 1.527628,0.360085"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="0.649807" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" rx="0.838801" y="202.851471" x="84.255138" height="26.434283" width="94.537572" id="rect3815"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="0.792138" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" id="rect3817" width="131.339764" height="28.275376" x="282.077514" y="201.912133" rx="1.165334"/>
<path stroke="#000000" fill="none" stroke-width="0.865499px" id="path3823" d="m347.74739,201.086282l0,28.351986"/>
<text transform="matrix(0.7776670647796514,0,0,1.19475416519067,-52.30106724263901,-77.52018902784596) " font-size="12.623897px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="434.634023" y="248.956571" id="text3835">
<tspan stroke="null" font-size="15.579311px" font-weight="bold" font-family="Monospace" x="435.91992" y="253.141532" id="tspan3837">n2-eth0</tspan>
</text>
<text transform="matrix(0.9031157255303414,0,0,1.0287949657006918,-2.8313337284492768,-13.069358400177762) " font-size="13.163442px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="110.835751" y="225.210496" id="text3863">
<tspan stroke="null" font-size="16.245171px" font-weight="bold" font-family="Monospace" x="111.943029" y="230.070551" id="tspan3865">n1-eth0</tspan>
</text>
<path stroke="#000000" fill="none" stroke-width="0.992521px" id="path3887" d="m131.263954,229.882774l0,67.221296l176.555867,-0.960307l1.337531,-65.300682"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="0.676601" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" id="rect3891" width="95.679394" height="28.317195" x="515.346399" y="202.85306" rx="0.848932"/>
<path stroke="#000000" fill="none" stroke-width="0.992521px" d="m383.833251,230.842992l0,67.221296l176.555867,-0.960307l1.337531,-65.300682" id="path3897"/>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="164.136782" y="409.888383" id="text3907">
<tspan stroke="null" id="tspan3915" x="165.159464" y="415.15046">isolated point to point link</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3919" y="409.573373" x="429.378262" xml:space="preserve">
<tspan stroke="null" y="414.83545" x="430.400944" id="tspan3921">isolated point to point link</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3923" y="428.078233" x="194.615642" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="433.34031" x="195.638324" id="tspan3925">(eg: 1Mbps, 10ms)</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3927" y="409.888383" x="164.136782" xml:space="preserve">
<tspan stroke="null" y="415.15046" x="165.159464" id="tspan3929">Isolated point to point link</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="429.378262" y="409.573373" id="text3931">
<tspan stroke="null" id="tspan3933" x="430.400944" y="414.83545">Isolated point to point link</tspan>
</text>
<text transform="matrix(0.877827228897152,0,0,1.0584326041598764,-53.30106731891522,-78.4233265445007) " font-size="13.706223px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3935" y="282.545218" x="661.482605" xml:space="preserve">
<tspan stroke="null" font-size="16.915024px" font-weight="bold" font-family="Monospace" id="tspan3937" y="287.269185" x="662.621781">n3-eth0</tspan>
</text>
<text transform="matrix(0.7776670647796514,0,0,1.19475416519067,-52.30106724263901,-77.52018902784596) " font-size="12.623897px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3939" y="248.297391" x="520.751053" xml:space="preserve">
<tspan stroke="null" font-size="15.579311px" font-weight="bold" font-family="Monospace" id="tspan3941" y="252.482352" x="522.03695">n2-eth1</tspan>
</text>
<text transform="matrix(0.8745385143393076,0,0,1.0624128521471832,-2.8313338199928846,-14.069358364146652) " font-size="16.205975px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3943" y="80.648481" x="141.655977" xml:space="preserve">
<tspan stroke="null" font-size="20px" font-weight="bold" font-family="Monospace" id="tspan3945" y="85.354749" x="142.799437">n1</tspan>
</text>
<text transform="matrix(0.8745385143393076,0,0,1.0624128521471832,-2.8313338199928846,-14.069358364146652) " font-size="16.205975px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="385.430517" y="78.840861" id="text3955">
<tspan stroke="null" font-size="20px" font-weight="bold" font-family="Monospace" x="386.573977" y="83.547129" id="tspan3957">n2</tspan>
</text>
<text transform="matrix(0.8745385143393076,0,0,1.0624128521471832,-2.8313338199928846,-14.069358364146652) " font-size="16.205975px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3959" y="79.181231" x="632.310457" xml:space="preserve">
<tspan stroke="null" font-size="20px" font-weight="bold" font-family="Monospace" id="tspan3961" y="83.887499" x="633.453917">n3</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="125.371536" y="171.060971" id="text3967">
<tspan stroke="null" font-weight="normal" id="tspan3969" x="126.421253" y="176.187525">(NDN Container)</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3979" y="170.076461" x="352.011746" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="175.203015" x="353.061463" id="tspan3981">(NDN Container)</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="580.077396" y="169.091931" id="text3983">
<tspan stroke="null" font-weight="normal" id="tspan3985" x="581.127113" y="174.218485">(NDN Container)</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3987" y="193.704961" x="123.946116" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="198.831515" x="124.995833" id="tspan3989">NFD</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="140.791686" y="208.664491" id="text3991">
<tspan stroke="null" font-weight="normal" id="tspan3993" x="141.841403" y="213.791045">n1.sock</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="123.946116" y="225.286191" id="text3995">
<tspan stroke="null" font-weight="bold" id="tspan3997" x="124.995833" y="230.412745">NLSR</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3999" y="240.245731" x="138.385176" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="245.372285" x="139.434893" id="tspan4001">%C1.Router/n1</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="352.011746" y="191.735901" id="text4003">
<tspan stroke="null" font-weight="bold" id="tspan4005" x="353.061463" y="196.862455">NFD</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4007" y="206.695431" x="366.450896" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="211.821985" x="367.500613" id="tspan4009">n2.sock</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4011" y="223.317141" x="352.011746" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="228.443695" x="353.061463" id="tspan4013">NLSR</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="366.450896" y="238.276671" id="text4015">
<tspan stroke="null" font-weight="normal" id="tspan4017" x="367.500613" y="243.403225">%C1.Router/n2</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4019" y="190.751371" x="582.928226" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="195.877925" x="583.977943" id="tspan4021">NFD</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="599.773686" y="205.710911" id="text4023">
<tspan stroke="null" font-weight="normal" id="tspan4025" x="600.823403" y="210.837465">n3.sock</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="582.928226" y="222.332611" id="text4027">
<tspan stroke="null" font-weight="bold" id="tspan4029" x="583.977943" y="227.459165">NLSR</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4031" y="237.292141" x="597.367186" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="242.418695" x="598.416903" id="tspan4033">%C1.Router/n3</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4035" y="102.475413" x="322.701992" xml:space="preserve">
<tspan stroke="null" y="107.73749" x="323.724674" id="tspan4037">Isolated NDN nodes</tspan>
</text>
<text transform="matrix(0.935021961689298,0,0,0.9936889310882339,-2.9798247609055646,-12.086171479984756) " font-size="11.279781px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="75.549398" y="206.131281" id="text4039">
<tspan stroke="null" id="tspan4041" x="76.618892" y="211.163037">Private network space</tspan>
</text>
<text transform="matrix(0.935021961689298,0,0,0.9936889310882339,-2.9798247609055646,-12.086171479984756) " font-size="11.279781px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4043" y="206.946991" x="308.474828" xml:space="preserve">
<tspan stroke="null" y="211.978747" x="309.544322" id="tspan4045">Private network space</tspan>
</text>
<text transform="matrix(0.935021961689298,0,0,0.9936889310882339,-2.9798247609055646,-12.086171479984756) " font-size="11.279781px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="540.174348" y="206.131281" id="text4047">
<tspan stroke="null" id="tspan4049" x="541.243842" y="211.163037">Private network space</tspan>
</text>
<text xml:space="preserve" text-anchor="start" font-family="Helvetica,Arial,sans-serif" font-size="15px" id="svg_1" y="377" x="203.5" stroke-width="null" stroke="null" fill="#333">Figure: Relationship between Minindn and Mininet</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

+186
View File
@@ -0,0 +1,186 @@
Release Notes
=============
Mini-NDN version 0.4.0 (changes since version 0.3.0)
----------------------------------------------------
Release date: January 10, 2018
**New features**:
- Use SIGQUIT to quit Mini-NDN, SIGINT to kill programs
- Use Infoedit to edit NFD and NLSR configuration files
- Use nlsr.conf installed in the system
- Provide a Vagrantfile to setup Mini-NDN and NDN
- Provide option to disable NLSR
- Provide an option to run NLSR in dry-run mode
- Add option to specify whether to use TCP or UDP face in nlsr.conf
- Add option to specify arbitrary arguments to use in experiments
- Include a single option to install Mini-NDN and all the dependencies
**Bug fixes**:
- Fix "key does not exist error" after NLSR starts
- Update install.sh to call ldconfig after installing ChronoSync
- Add hyperbolic coordinates to default topology
**Misc changes**:
- Add an experiment to test nlsrc
- Create faces in NFD for each neighbor in NLSR
- Update to latest ndn-cxx
- Use /tmp/minindn folder as default work dir instead of /tmp
Mini-NDN version 0.3.0 (changes since version 0.2.0)
----------------------------------------------------
Release date: March 3, 2017
**New features**:
- Mini-NDN cluster edition
- New experiments for making NLSR testing easier
**Bug fixes**:
- Set site name correctly
- Install missing certificates in NLSR security config
- Fix quitting of NLSR due to key not found error
**Misc changes**:
- Removed nlsr.conf file, generate it within the code
- Use argparse instead of deprecated optparse
- Update security config section for NLSR
- Change mininet prompt to mini-ndn
- Set network name at one place
- Update install.sh script to install openssl
- Update install.sh script to install cryptopp from package instead of
compiling from source
- Update install.sh to clean build folder every time to get rid of
removed files such as old experiments
- Fix old code - use net.hosts instead of storing hosts in a variable
- Use nfdc instead of deprecated nfd-status
Mini-NDN version 0.2.0 (changes since version 0.1.1)
----------------------------------------------------
Release date: August 18, 2016
**New features**:
- Automatic security configuration for NLSR
- Use /usr/local/etc/ndn/nfd.conf as default config file for NFD
- Class to monitor /proc/$PID/stat file for PID
- Mini-NDN exits gracefully on SIGINT and non-convergence
- Faster Mini-NDN install script - does not do apt-get update everytime
- NLSR is launched with explicit config file for easier process
identification
- Add and update more documentation
**Bug fixes**:
- NFD is killed correctly on exit
- Best route strategy is set correctly
Mini-NDN version 0.1.1 (changes since version 0.1.0)
----------------------------------------------------
Release date: November 4, 2015
**New features**:
- Use nfd.conf.sample from currently installed NFD
- Add working directory option to allow execution environment outside
of /tmp
- Add results directory option to store experiment results after
completion
- Add support for switches in GUI and configuration file
- Add failNode and recoverNode methods to Experiment class
- Add most connected node (MCN) failure experiment
- Add option to specify percentage of nodes pinged
**Code changes**:
- Refactor program options into container class
- Remove unused "FIB Entries" option from NDN host options
**Bug fixes**:
- Abort start up if experiment name is invalid
- Restart pings after recovery in failure experiment
Mini-NDN version 0.1.0 (initial release)
----------------------------------------
Release date: July 15, 2015
Mini-NDN is a lightweight networking emulation tool that enables
testing, experimentation, and research on the NDN platform. Based on
Mininet, Mini-NDN uses the NDN libraries, NFD, NLSR, and tools released
by the `NDN project <http://named-data.net/codebase/platform/>`__ to
emulate an NDN network on a single system.
**Included features**:
- Run a complete NDN network on a single system
- Automatic configuration of NLSR to provide a routable NDN network
- Supports user created NDN applications
- Create a topology using the included Mini-NDN Edit GUI application
- Allows individual configuration of NFD and NLSR parameters for each
node
- Provides an experiment management framework for easy creation of
custom networking experiments
- Uses a simple topology file format to define hosts, links, and
configuration values
- Configure network link parameters including bandwidth, delay, and
loss rate
- Includes a pre-configured topology file to replicate the NDN testbed
+18
View File
@@ -0,0 +1,18 @@
Video Tutorials
===============
Maybe outdated since version 0.5.0.
.. raw:: html
<div id="video-container" class="col-md-6 ">
<p>Mini-NDN Demo at ACM, 2017</p>
<iframe width="400" height="230" src="https://www.youtube.com/embed/xYRPHZe18o0" frameborder="0" allowfullscreen=""></iframe>
</div>
.. raw:: html
<div id="video-container" class="col-md-6 "">
<p>Mini-NDN Overview </p>
<iframe width="400" height="230" src="https://www.youtube.com/embed/Da7t8yBWzv0" frameborder="0" allowfullscreen="">
</div>
@@ -1,6 +1,6 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -21,29 +21,33 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from mininet.log import setLogLevel, info
import time
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.ip_routing_helper import IPRoutingHelper
class PingallExperiment(Experiment):
if __name__ == '__main__':
setLogLevel('info')
def __init__(self, args):
Minindn.cleanUp()
Minindn.verifyDependencies()
Experiment.__init__(self, args)
self.COLLECTION_PERIOD_BUFFER = 10
print "Using {} traffic".format(self.options.pctTraffic)
ndn = Minindn()
def setup(self):
if self.options.nPings != 0:
Experiment.setup(self)
ndn.start()
def run(self):
if self.options.nPings == 0:
return
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Starting NLSR on nodes\n')
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
self.startPctPings()
# Calculate all routes for IP routing
IPRoutingHelper.calcAllRoutes(ndn.net)
info("IP routes configured, start ping\n")
# For pingall experiment sleep for the number of pings + some offset
time.sleep(self.options.nPings + self.COLLECTION_PERIOD_BUFFER)
ndn.net.pingAll()
Experiment.register("pingall", PingallExperiment)
ndn.net.stop()
@@ -21,27 +21,29 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.routing_helper import IPRoutingHelper
from mininet.log import setLogLevel, info
from mininet.log import info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
if __name__ == '__main__':
setLogLevel('info')
class IpRoutingExperiment(Experiment):
Minindn.cleanUp()
Minindn.verifyDependencies()
def __init__(self, args):
Experiment.__init__(self, args)
ndn = Minindn()
def setup(self):
pass
ndn.start()
def run(self):
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Starting NLSR on nodes\n')
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
# Calculate all routes for IP routing
IPRoutingHelper.calcAllRoutes(self.net)
info("IP routes configured, start ping\n")
MiniNDNCLI(ndn.net)
self.net.pingAll()
Experiment.register("ip-routing", IpRoutingExperiment)
ndn.stop()
+79
View File
@@ -0,0 +1,79 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
topo = Topo()
h1 = topo.addHost('h1')
h2 = topo.addHost('h2')
topo.addLink(h1, h2, delay='10ms')
ndn = Minindn(parser=getParser(), topo=topo)
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, [], Nlsr)
host1 = ndn.net.hosts[0]
nlsrs.startOnNode(host1, security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
expectedTotalCount = 500
for i in range(0, expectedTotalCount):
host1.cmd('nlsrc advertise /long/name/to/exceed/max/packet/size/host1/{}'.format(i))
time.sleep(60)
host2 = ndn.net.hosts[1]
nlsrs.startOnNode(host2, security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
time.sleep(60)
advertiseCount = int(host2.cmd('nfdc fib | grep host1 | wc -l'))
info(advertiseCount)
if advertiseCount == expectedTotalCount:
info('\nSuccessfully advertised {} prefixes\n'.format(expectedTotalCount))
else:
info('\nAdvertising {} prefixes failed. Exiting...\n'.format(expectedTotalCount))
ndn.stop()
sys.exit(1)
ndn.stop()
+64
View File
@@ -0,0 +1,64 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, [], Nlsr)
i = 1
info('Starting NLSR on nodes\n')
for host in ndn.net.hosts:
nlsrs.startOnNode(host, security=args.security, sync=args.sync, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
# Wait 1/2 minute between starting NLSRs
# Wait 1 hour before starting last NLSR
if i == len(ndn.net.hosts) - 1:
info('Sleeping 1 hour before starting last NLSR\n')
time.sleep(3600)
else:
time.sleep(30)
i += 1
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
ndn.stop()
+90
View File
@@ -0,0 +1,90 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from minindn.helpers.nfdc import Nfdc
from minindn.helpers.ndnpingclient import NDNPingClient
from nlsr_common import getParser
def mcnFailure(ndn, nfds, nlsrs, args):
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
if args.nPings != 0:
Experiment.setupPing(ndn.net.hosts, Nfdc.STRATEGY_BEST_ROUTE)
pingedDict = Experiment.startPctPings(ndn.net, args.nPings, args.pctTraffic)
PING_COLLECTION_TIME_BEFORE_FAILURE = 60
PING_COLLECTION_TIME_AFTER_RECOVERY = 120
time.sleep(PING_COLLECTION_TIME_BEFORE_FAILURE)
mcn = max(ndn.net.hosts, key=lambda host: len(host.intfNames()))
info('Bringing down node {}\n'.format(mcn.name))
nlsrs[mcn.name].stop()
nfds[mcn.name].stop()
time.sleep(args.ctime)
info('Bringing up node {}\n'.format(mcn.name))
nfds[mcn.name].start()
nlsrs[mcn.name].start()
# Restart pings
if args.nPings != 0:
Experiment.setupPing([mcn], Nfdc.STRATEGY_BEST_ROUTE)
for nodeToPing in pingedDict[mcn]:
NDNPingClient.ping(mcn, nodeToPing, PING_COLLECTION_TIME_AFTER_RECOVERY)
time.sleep(PING_COLLECTION_TIME_AFTER_RECOVERY)
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
mcnFailure(ndn, nfds, nlsrs, args)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+109
View File
@@ -0,0 +1,109 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from minindn.helpers.nfdc import Nfdc
from minindn.helpers.ndnpingclient import NDNPingClient
from nlsr_common import getParser
def multipleFailure(ndn, nfds, nlsrs, args):
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
Experiment.setupPing(ndn.net.hosts, Nfdc.STRATEGY_BEST_ROUTE)
PING_COLLECTION_TIME_BEFORE_FAILURE = 60
FAILURE_INTERVAL = 60
RECOVERY_INTERVAL = 60
# This is the number of pings required to make it through the full experiment
nInitialPings = (PING_COLLECTION_TIME_BEFORE_FAILURE +
len(ndn.net.hosts) * (FAILURE_INTERVAL + RECOVERY_INTERVAL))
print('Scheduling with {} initial pings'.format(nInitialPings))
pingedDict = Experiment.startPctPings(ndn.net, nInitialPings, args.pctTraffic)
time.sleep(PING_COLLECTION_TIME_BEFORE_FAILURE)
nNodesRemainingToFail = len(ndn.net.hosts)
for host in ndn.net.hosts:
# Fail the node
info('Bringing down node {}\n'.format(host.name))
nlsrs[host.name].stop()
nfds[host.name].stop()
# Stay in failure state for FAILURE_INTERVAL seconds
time.sleep(FAILURE_INTERVAL)
# Bring the node back up
start_time = time.time()
info('Bringing up node {}\n'.format(host.name))
nfds[host.name].start()
nlsrs[host.name].start()
Experiment.setupPing([host], Nfdc.STRATEGY_BEST_ROUTE)
recovery_time = int(time.time() - start_time)
# Number of pings required to reach the end of the test
nNodesRemainingToFail -= 1
nPings = ((RECOVERY_INTERVAL - recovery_time) +
nNodesRemainingToFail * (FAILURE_INTERVAL + RECOVERY_INTERVAL))
info('Scheduling with {} remaining pings\n'.format(nPings))
# Restart pings
for nodeToPing in pingedDict[host]:
NDNPingClient.ping(host, nodeToPing, nPings)
time.sleep(RECOVERY_INTERVAL - recovery_time)
#Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
multipleFailure(ndn, nfds, nlsrs, args)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+57
View File
@@ -0,0 +1,57 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import argparse
def getParser():
parser = argparse.ArgumentParser()
parser.add_argument('--ctime', type=int, default=60,
help='Specify convergence time for the topology (Default: 60 seconds)')
parser.add_argument('--faces', type=int, default=3,
help='Specify number of max faces per prefix for NLSR 0-60')
parser.add_argument('--routing', dest='routingType', default='link-state',
choices=['link-state', 'hr', 'dry'],
help='''Choose routing type, dry = link-state is used
but hr is calculated for comparision.''')
parser.add_argument('--sync', dest='sync', default='psync',
choices=['chronosync', 'psync'],
help='choose the sync protocol to be used by NLSR.')
parser.add_argument('--security', action='store_true', dest='security',
help='Enables NLSR security')
parser.add_argument('--face-type', dest='faceType', default='udp', choices=['udp', 'tcp'])
parser.add_argument('--no-cli', action='store_false', dest='isCliEnabled',
help='Run experiments and exit without showing the command line interface')
parser.add_argument('--pct-traffic', dest='pctTraffic', type=float, default=1.0,
help='Specify the percentage of nodes each node should ping')
parser.add_argument('--nPings', type=int, default=300,
help='Number of pings to perform between each node in the experiment')
return parser
+63
View File
@@ -0,0 +1,63 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from minindn.helpers.nfdc import Nfdc
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType,
logLevel='ndn.*=TRACE:nlsr.*=TRACE')
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=False)
if args.nPings != 0:
Experiment.setupPing(ndn.net.hosts, Nfdc.STRATEGY_BEST_ROUTE)
Experiment.startPctPings(ndn.net, args.nPings, args.pctTraffic)
time.sleep(args.nPings + 10)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+84
View File
@@ -0,0 +1,84 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
firstNode = ndn.net.hosts[0]
if args.security:
firstNode.cmd('ndnsec-set-default /ndn/{}-site/%C1.Operator/op'.format(firstNode.name))
info('Testing advertise\n')
firstNode.cmd('nlsrc advertise /testPrefix')
time.sleep(30)
for host in ndn.net.hosts:
if host.name != firstNode.name:
if (int(host.cmd('nfdc fib | grep testPrefix | wc -l')) != 1 or
int(host.cmd('nlsrc status | grep testPrefix | wc -l')) != 1):
info('Advertise test failed\n')
ndn.stop()
sys.exit(1)
info('Testing withdraw\n')
firstNode.cmd('nlsrc withdraw /testPrefix')
time.sleep(30)
for host in ndn.net.hosts:
if host.name != firstNode.name:
if (int(host.cmd('nfdc fib | grep testPrefix | wc -l')) != 0 or
int(host.cmd('nlsrc status | grep testPrefix | wc -l')) != 0):
info('Withdraw test failed\n')
ndn.stop()
sys.exit(1)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+81
View File
@@ -0,0 +1,81 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.helpers.nfdc import Nfdc
def registerRouteToAllNeighbors(ndn, host, syncPrefix):
for node in ndn.net.hosts:
for neighbor in node.connectionsTo(host):
ip = node.IP(neighbor[0])
Nfdc.createFace(host, ip)
Nfdc.registerRoute(host, syncPrefix, ip)
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn()
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
syncPrefix = "/sync"
numUserPrefixesPerNode = 2
maxUpdatesPerUserPrefixPerNode = 3
for host in ndn.net.hosts:
Nfdc.setStrategy(host, syncPrefix, Nfdc.STRATEGY_MULTICAST)
registerRouteToAllNeighbors(ndn, host, syncPrefix)
info('Starting psync-full-sync on all the nodes\n')
for host in ndn.net.hosts:
host.cmd('export NDN_LOG=examples.FullSyncApp=INFO')
host.cmd('psync-full-sync {} {} {} {} &> psync.logs &'
.format(syncPrefix, host.name, numUserPrefixesPerNode,
maxUpdatesPerUserPrefixPerNode))
info('Sleeping 5 minutes for convergence\n')
# Estimated time for 4 node default topology
time.sleep(300)
totalUpdates = int(host.cmd('grep -r Update {}/*/psync.logs | wc -l'
.format(args.workDir)))
expectedUpdates = (maxUpdatesPerUserPrefixPerNode *
len(ndn.net.hosts) * (len(ndn.net.hosts) - 1) * numUserPrefixesPerNode)
if totalUpdates == expectedUpdates:
info('PSync full sync has successfully converged.\n')
else:
info('PSync full sync convergence was not successful. Exiting...\n')
ndn.stop()
sys.exit(1)
+67
View File
@@ -0,0 +1,67 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
if __name__ == '__main__':
setLogLevel('info')
topo = Topo()
topo.addHost('h1')
ndn = Minindn(topo=topo)
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
host1 = ndn.net.hosts[0]
host1.cmd('export NDN_LOG=examples.PartialSyncProducerApp=INFO')
host1.cmd('psync-producer /sync /{} 10 1 &> producer.log &'.format(host1.name))
time.sleep(1)
host1.cmd('export NDN_LOG=examples.PartialSyncConsumerApp=INFO:$NDN_LOG')
host1.cmd('psync-consumer /sync 5 &> consumer.log &')
info('Sleeping 90 seconds for convergence\n')
time.sleep(90)
consumerSubs = int(host1.cmd('cat consumer.log | grep -c Subscribing'))
consumerUpdates = int(host1.cmd('cat consumer.log | grep -c Update'))
producerPublish = int(host1.cmd('cat producer.log | grep -c Publish'))
if consumerSubs == 5 and consumerUpdates == 5 and producerPublish == 10:
info('PSync partial sync has successfully converged.\n')
else:
info('PSync partial sync convergence was not successful. Exiting...\n')
ndn.stop()
sys.exit(1)
+100
View File
@@ -0,0 +1,100 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import argparse
import sys
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.helpers.ndn_routing_helper import NdnRoutingHelper
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
parser = argparse.ArgumentParser()
parser.add_argument('--face-type', dest='faceType', default='udp', choices=['udp', 'tcp'])
parser.add_argument('--routing', dest='routingType', default='link-state',
choices=['link-state', 'hr', 'dry'],
help='''Choose routing type, dry = link-state is used
but hr is calculated for comparision.''')
'''
Experiment run with default topology, test cases won't work with other topologies
# With calculateNPossibleRoutes,
10 # routing = hr, N = All, from A, 3 routes needs to added to NFD.
a +++++++ b # a - b -- cost 10
+ + # a - c -- cost 10
10 + + 10 # a - d -- cost 20
+ + # Same goes for B being a source.
c d #
'''
topo = Topo()
a = topo.addHost('a')
b = topo.addHost('b')
c = topo.addHost('c')
d = topo.addHost('d')
topo.addLink(a, b, delay='10ms')
topo.addLink(a, c, delay='10ms')
topo.addLink(b, d, delay='10ms')
ndn = Minindn(parser=parser, topo=topo)
ndn.start()
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Adding static routes to NFD\n')
grh = NdnRoutingHelper(ndn.net, ndn.args.faceType, ndn.args.routingType)
# For all host, pass ndn.net.hosts or a list, [ndn.net['a'], ..] or [ndn.net.hosts[0],.]
grh.addOrigin([ndn.net['a']], ["/abc"])
grh.calculateNPossibleRoutes()
'''
prefix "/abc" is advertise from node A, it should be reachable from all other nodes.
'''
routesFromA = ndn.net['a'].cmd("nfdc route | grep -v '/localhost/nfd'")
if '/ndn/b-site/b' not in routesFromA or \
'/ndn/c-site/c' not in routesFromA or \
'/ndn/d-site/d' not in routesFromA:
info("Route addition failed\n")
routesToPrefix = ndn.net['b'].cmd("nfdc fib | grep '/abc'")
if '/abc' not in routesToPrefix:
info("Missing route to advertised prefix, Route addition failed\n")
ndn.net.stop()
sys.exit(1)
info('Route addition to NFD completed\n')
MiniNDNCLI(ndn.net)
ndn.stop()
+106 -124
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# -*- Mode:bash; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -85,93 +85,85 @@ if [[ $DIST == Fedora ]]; then
fi
fi
function forwarder {
if [[ $cxx != true ]]; then
ndncxx
cxx="true"
fi
NDN_SRC="ndn-src"
if [[ $DIST == Ubuntu || $DIST == Debian ]]; then
$install libpcap-dev pkg-config
fi
NDN_GITHUB="https://github.com/named-data"
if [[ $DIST == Fedora ]]; then
$install libpcap-devel
fi
NDN_CXX_VERSION="master"
NFD_VERSION="master"
PSYNC_VERSION="master"
CHRONOSYNC_VERSION="master"
NLSR_VERSION="master"
NDN_TOOLS_VERSION="master"
git clone --depth 1 https://github.com/named-data/NFD
cd NFD
./waf configure --without-websocket
./waf
sudo ./waf install
cd ../
if [ $SUDO_USER ]; then
REAL_USER=$SUDO_USER
else
REAL_USER=$(whoami)
fi
function patchDummy {
git -C $NDN_SRC/ndn-cxx apply $(pwd)/patches/ndn-cxx-dummy-keychain-from-ndnsim.patch
if [[ "$?" -ne 0 ]]; then
echo "Patch might already be applied"
fi
}
function routing {
if [[ $cxx != true ]]; then
ndncxx
cxx="true"
function ndn_install {
mkdir -p $NDN_SRC
name=$1
version=$2
wafOptions=$3
if [[ $version == "master" ]]; then
if [[ -d "$NDN_SRC/$name" ]]; then
pushd $NDN_SRC/$name
git checkout master
else
git clone --depth 1 $NDN_GITHUB/$name $NDN_SRC/$name
pushd $NDN_SRC/$name
fi
else
if [[ -d $NDN_SRC/$name ]]; then
pushd $NDN_SRC/$name
if [[ $(git rev-parse --is-shallow-repository) == "true" ]]; then
git fetch --unshallow
git fetch --all
fi
else
git clone $NDN_GITHUB/$name $NDN_SRC/$name
pushd $NDN_SRC/$name
fi
git checkout $version -b version-$version || git checkout version-$version
fi
git clone --depth 1 https://github.com/named-data/PSync
cd PSync
./waf configure
./waf
sudo ./waf install
sudo ldconfig
cd ../
git clone --depth 1 https://github.com/named-data/ChronoSync
cd ChronoSync
./waf configure
./waf
sudo ./waf install
sudo ldconfig
cd ../
git clone --depth 1 https://github.com/named-data/NLSR
cd NLSR
./waf configure
./waf
sudo ./waf install
cd ../
# User must use the same python version as root to use ./waf outside of this script
sudo -E -u $REAL_USER ./waf configure $wafOptions
sudo -E -u $REAL_USER ./waf && sudo ./waf install && sudo ldconfig
popd
}
function ndncxx {
function ndn {
if [[ updated != true ]]; then
$update
updated="true"
fi
if [[ $DIST == Ubuntu || $DIST == Debian ]]; then
$install git libsqlite3-dev libboost-all-dev make g++ libssl-dev
$install git libsqlite3-dev libboost-all-dev make g++ libssl-dev libpcap-dev pkg-config python-pip
fi
if [[ $DIST == Fedora ]]; then
$install gcc-c++ sqlite-devel boost-devel openssl-devel
$install gcc-c++ sqlite-devel boost-devel openssl-devel libpcap-devel python-pip
fi
git clone --depth 1 https://github.com/named-data/ndn-cxx
cd ndn-cxx
./waf configure
./waf
sudo ./waf install
sudo ldconfig
cd ../
}
function tools {
if [[ $cxx != true ]]; then
ndncxx
cxx="true"
fi
git clone --depth 1 https://github.com/named-data/ndn-tools
cd ndn-tools
./waf configure
./waf
sudo ./waf install
cd ../
ndn_install ndn-cxx $NDN_CXX_VERSION
ndn_install NFD $NFD_VERSION --without-websocket
ndn_install PSync $PSYNC_VERSION --with-examples
ndn_install ChronoSync $CHRONOSYNC_VERSION
ndn_install NLSR $NLSR_VERSION
ndn_install ndn-tools $NDN_TOOLS_VERSION
infoedit
}
function mininet {
@@ -185,16 +177,17 @@ function mininet {
fi
git clone --depth 1 https://github.com/mininet/mininet
cd mininet
sudo ./util/install.sh -fnv
cd ../
pushd mininet
sudo ./util/install.sh -nv
popd
}
function infoedit {
git clone --depth 1 https://github.com/NDN-Routing/infoedit.git
cd infoedit
git clone --depth 1 https://github.com/NDN-Routing/infoedit.git $NDN_SRC/infoedit
pushd $NDN_SRC/infoedit
rm infoedit
sudo make install
cd ../
popd
}
function minindn {
@@ -220,7 +213,7 @@ function minindn {
sudo cp topologies/minindn.ucla.conf "$install_dir"
sudo cp topologies/minindn.testbed.conf "$install_dir"
sudo cp topologies/current-testbed.conf "$install_dir"
sudo python setup.py clean --all install
sudo python setup.py develop
}
function ndn_cpp {
@@ -238,14 +231,14 @@ function ndn_cpp {
return
fi
git clone --depth 1 https://github.com/named-data/ndn-cpp
cd ndn-cpp
git clone --depth 1 $NDN_GITHUB/ndn-cpp $NDN_SRC/ndn-cpp
pushd $NDN_SRC/ndn-cpp
./configure
proc=$(nproc)
make -j$proc
sudo make install
sudo ldconfig
cd ..
popd
}
function pyNDN {
@@ -264,13 +257,13 @@ function pyNDN {
fi
sudo pip install cryptography trollius protobuf pytest mock
git clone --depth 1 https://github.com/named-data/PyNDN2
cd PyNDN2
git clone --depth 1 $NDN_GITHUB/PyNDN2 $NDN_SRC/PyNDN2
pushd $NDN_SRC/PyNDN2
# Update the user's PYTHONPATH.
echo "export PYTHONPATH=\$PYTHONPATH:`pwd`/python" >> ~/.bashrc
# Also update root's PYTHONPATH in case of running under sudo.
echo "export PYTHONPATH=\$PYTHONPATH:`pwd`/python" | sudo tee -a /root/.bashrc > /dev/null
cd ..
popd
}
function ndn_js {
@@ -291,7 +284,7 @@ function ndn_js {
sudo ln -fs /usr/bin/nodejs /usr/bin/node
sudo npm install -g mocha
sudo npm install rsa-keygen sqlite3
git clone --depth 1 https://github.com/named-data/ndn-js
git clone --depth 1 $NDN_GITHUB/ndn-js $NDN_SRC/ndn-js
}
function jNDN {
@@ -309,30 +302,10 @@ function jNDN {
return
fi
git clone --depth 1 https://github.com/named-data/jndn
cd jndn
git clone --depth 1 $NDN_GITHUB/jndn $NDN_SRC/jndn
pushd $NDN_SRC/jndn
mvn install
cd ..
}
function argcomplete {
if [[ $SHELL == "/bin/bash" ]]; then
$install bash-completion
$install python-argcomplete
if ! grep -q 'eval "$(register-python-argcomplete minindn)"' ~/.bashrc; then
echo 'eval "$(register-python-argcomplete minindn)"' >> ~/.bashrc
fi
source ~/.bashrc
elif [[ $SHELL == "/bin/zsh" ]] || [[ $SHELL == "/usr/bin/zsh" ]]; then
$install bash-completion
$install python-argcomplete
if ! grep -z -q 'autoload bashcompinit\sbashcompinit\seval "$(register-python-argcomplete minindn)"' ~/.zshrc; then
echo -e 'autoload bashcompinit\nbashcompinit\neval "$(register-python-argcomplete minindn)"' >> ~/.zshrc
fi
source ~/.zshrc
else
echo "Skipping argomplete install..."
fi
popd
}
function commonClientLibraries {
@@ -342,47 +315,56 @@ function commonClientLibraries {
jNDN
}
function buildDocumentation {
sphinxInstalled=$(pip show sphinx | wc -l)
sphinxRtdInstalled=$(pip show sphinx_rtd_theme | wc -l)
if [[ $sphinxInstalled -eq "0" ]]; then
pip install sphinx
fi
if [[ $sphinxRtdInstalled -eq "0" ]]; then
pip install sphinx_rtd_theme
fi
cd docs
make clean
make html
}
function usage {
printf '\nUsage: %s [-a]\n\n' $(basename $0) >&2
printf 'options:\n' >&2
printf -- ' -a: install all the required dependencies\n' >&2
printf -- ' -b: install autocomplete for Bash and Zsh users\n' >&2
printf -- ' -e: install infoedit\n' >&2
printf -- ' -f: install NFD\n' >&2
printf -- ' -c: install Common Client Libraries\n' >&2
printf -- ' -d: build documentation\n' >&2
printf -- ' -h: print this (H)elp message\n' >&2
printf -- ' -i: install mini-ndn\n' >&2
printf -- ' -m: install mininet and dependencies\n' >&2
printf -- ' -r: install NLSR\n' >&2
printf -- ' -t: install tools\n' >&2
printf -- ' -c: install Common Client Libraries\n' >&2
printf -- ' -n: install NDN dependencies of mini-ndn including infoedit\n' >&2
printf -- ' -p: patch ndn-cxx with dummy key chain\n' >&2
exit 2
}
if [[ $# -eq 0 ]]; then
usage
else
while getopts 'abemfrtic' OPTION
while getopts 'acdhimnp' OPTION
do
case $OPTION in
a)
forwarder
minindn
ndn
mininet
routing
tools
infoedit
argcomplete
minindn
commonClientLibraries
break
;;
b) argcomplete;;
e) infoedit;;
f) forwarder;;
c) commonClientLibraries;;
d) buildDocumentation;;
h) usage;;
i) minindn;;
m) mininet;;
r) routing;;
t) tools;;
c) commonClientLibraries;;
n) ndn;;
p) patchDummy;;
?) usage;;
esac
done
+1
View File
@@ -0,0 +1 @@
__version__ = '0.5.0'
File renamed without changes.
@@ -1,6 +1,6 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -21,29 +21,36 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from mininet.node import Node
class ArgumentsExperiment(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
self.ds = self.options.arguments.ds
self.logging = self.options.arguments.logging
class AppManager(object):
def __init__(self, minindn, hosts, cls, **appParams):
self.cls = cls
self.apps = []
for host in hosts:
# Don't run NDN apps on switches
if isinstance(host, Node):
self.startOnNode(host, **appParams)
def start(self):
pass
minindn.cleanups.append(self.cleanup)
def setup(self):
pass
def startOnNode(self, host, **appParams):
app = self.cls(host, **appParams)
app.start()
self.apps.append(app)
def run(self):
print("Argument ds: {}".format(self.ds))
print("Argument logging: {}".format(self.logging))
def cleanup(self):
for app in self.apps:
app.stop()
@staticmethod
def parseArguments(parser):
parser.add_argument("--ds", dest="ds", default="1000",
help="[Arguments Experiment] Number of data streams")
parser.add_argument("--logging", dest="logging", action="store_true",
help="[Arguments Experiment] Enable logging")
def __getitem__(self, nodeName):
for app in self.apps:
if app.node.name == nodeName:
return app
return None
Experiment.register("args-exp", ArgumentsExperiment)
def __iter__(self):
return self.apps.__iter__()
def __next__(self):
return self.apps.__next__()
@@ -1,6 +1,6 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -21,29 +21,28 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import os
from minindn.util import getPopen
class NdnApplication:
class Application(object):
def __init__(self, node):
self.node = node
self.isRunning = False
self.processId = ""
self.process = None
self.logfile = None
self.homeDir = self.node.params['params']['homeDir']
def start(self, command):
if self.isRunning is True:
try:
os.kill(int(self.processId), 0)
except OSError:
self.isRunning = False
# Make directory for log file
self.logDir = '{}/log'.format(self.homeDir)
self.node.cmd('mkdir -p {}'.format(self.logDir))
if self.isRunning is False:
self.node.cmd(command)
self.processId = self.node.cmd("echo $!")[:-1]
self.isRunning = True
def start(self, command, logfile, envDict=None):
if self.process is None:
self.logfile = open('{}/{}'.format(self.logDir, logfile), 'w')
self.process = getPopen(self.node, command.split(), envDict,
stdout=self.logfile, stderr=self.logfile)
def stop(self):
if self.isRunning and self.processId != "":
self.node.cmd("sudo kill {}".format(self.processId))
self.isRunning = False
if self.process is not None:
self.process.kill()
self.process = None
if self.logfile is not None:
self.logfile.close()
+74
View File
@@ -0,0 +1,74 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from minindn.apps.application import Application
from minindn.util import copyExistentFile
from minindn.minindn import Minindn
class Nfd(Application):
def __init__(self, node, logLevel='NONE', csSize=65536,
csPolicy='lru', csUnsolicitedPolicy='drop-all'):
Application.__init__(self, node)
self.logLevel = node.params['params'].get('nfd-log-level', logLevel)
self.confFile = '{}/nfd.conf'.format(self.homeDir)
self.logFile = 'nfd.log'
self.sockFile = '/var/run/{}.sock'.format(node.name)
self.ndnFolder = '{}/.ndn'.format(self.homeDir)
self.clientConf = '{}/client.conf'.format(self.ndnFolder)
# Copy nfd.conf file from /usr/local/etc/ndn or /etc/ndn to the node's home directory
# Use nfd.conf as default configuration for NFD, else use the sample
possibleConfPaths = ['/usr/local/etc/ndn/nfd.conf.sample', '/usr/local/etc/ndn/nfd.conf',
'/etc/ndn/nfd.conf.sample', '/etc/ndn/nfd.conf']
copyExistentFile(node, possibleConfPaths, self.confFile)
# Set log level
node.cmd('infoedit -f {} -s log.default_level -v {}'.format(self.confFile, self.logLevel))
# Open the conf file and change socket file name
node.cmd('infoedit -f {} -s face_system.unix.path -v {}'.format(self.confFile, self.sockFile))
# Set CS parameters
node.cmd('infoedit -f {} -s tables.cs_max_packets -v {}'.format(self.confFile, csSize))
node.cmd('infoedit -f {} -s tables.cs_policy -v {}'.format(self.confFile, csPolicy))
node.cmd('infoedit -f {} -s tables.cs_unsolicited_policy -v {}'.format(self.confFile, csUnsolicitedPolicy))
# Make NDN folder
node.cmd('mkdir -p {}'.format(self.ndnFolder))
# Copy client configuration to host
possibleClientConfPaths = ['/usr/local/etc/ndn/client.conf.sample', '/etc/ndn/client.conf.sample']
copyExistentFile(node, possibleClientConfPaths, self.clientConf)
# Change the unix socket
node.cmd('sudo sed -i "s|nfd.sock|{}.sock|g" {}'.format(node.name, self.clientConf))
if not Minindn.ndnSecurityDisabled:
# Generate key and install cert for /localhost/operator to be used by NFD
node.cmd('ndnsec-keygen /localhost/operator | ndnsec-install-cert -')
def start(self):
Application.start(self, 'nfd --config {}'.format(self.confFile), logfile=self.logFile)
Minindn.sleep(2)
+258
View File
@@ -0,0 +1,258 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import shutil
import os, sys
from mininet.clean import sh
from mininet.examples.cluster import RemoteMixin
from mininet.log import warn
from mininet.node import Switch
from minindn.apps.application import Application
from minindn.util import scp, copyExistentFile
from minindn.helpers.nfdc import Nfdc
from minindn.minindn import Minindn
class Nlsr(Application):
ROUTING_LINK_STATE = 'link-state'
ROUTING_HYPERBOLIC = 'hr'
ROUTING_DRY_RUN = 'dry'
SYNC_PSYNC = 'psync'
SYNC_CHRONOSYNC = 'chronosync'
def __init__(self, node, logLevel='NONE', security=False, sync=SYNC_PSYNC,
faceType='udp', nFaces=3, routingType=ROUTING_LINK_STATE):
Application.__init__(self, node)
self.network = '/ndn/'
self.node = node
self.parameters = self.node.params['params']
if self.parameters.get('nlsr-log-level', None) != None:
logLevel = self.parameters.get('nlsr-log-level')
if logLevel in ['NONE', 'WARN', 'INFO', 'DEBUG', 'TRACE']:
self.envDict = {'NDN_LOG': 'nlsr.*={}'.format(logLevel)}
else:
self.envDict = {'NDN_LOG': logLevel}
self.logFile = 'nlsr.log'
self.routerName = '/{}C1.Router/cs/{}'.format('%', node.name)
self.confFile = '{}/nlsr.conf'.format(self.homeDir)
self.security = security
self.sync = sync
self.faceType = faceType
self.infocmd = 'infoedit -f nlsr.conf'
self.parameters = self.node.params['params']
self.nFaces = nFaces
if routingType == Nlsr.ROUTING_HYPERBOLIC:
self.hyperbolicState = 'on'
elif routingType == Nlsr.ROUTING_DRY_RUN:
self.hyperbolicState = 'dry-run'
else:
self.hyperbolicState = 'off'
self.hyperRadius = self.parameters.get('radius', 0.0)
self.hyperAngle = self.parameters.get('angle', 0.0)
if ((self.hyperbolicState == 'on' or self.hyperbolicState == 'dry-run') and
(self.hyperRadius == 0.0 or self.hyperAngle == 0.0)):
warn('Hyperbolic coordinates in topology file are either missing or misconfigured.')
warn('Check that each node has one radius value and one or two angle value(s).')
sys.exit(1)
self.neighborIPs = []
possibleConfPaths = ['/usr/local/etc/ndn/nlsr.conf.sample', '/etc/ndn/nlsr.conf.sample']
copyExistentFile(node, possibleConfPaths, '{}/nlsr.conf'.format(self.homeDir))
self.createConfigFile()
if security and not Minindn.ndnSecurityDisabled:
self.createKeysAndCertificates()
def start(self):
self.createFaces()
Application.start(self, 'nlsr -f {}'.format(self.confFile), self.logFile, self.envDict)
Minindn.sleep(1)
def createFaces(self):
for ip in self.neighborIPs:
Nfdc.createFace(self.node, ip, self.faceType, isPermanent=True)
@staticmethod
def createKey(host, name, outputFile):
host.cmd('ndnsec-keygen {} > {}'.format(name, outputFile))
@staticmethod
def createCertificate(host, signer, keyFile, outputFile):
host.cmd('ndnsec-certgen -s {} -r {} > {}'.format(signer, keyFile, outputFile))
def createKeysAndCertificates(self):
securityDir = '{}/security'.format(self.parameters['workDir'])
if not os.path.exists(securityDir):
os.mkdir(securityDir)
rootName = self.network
rootCertFile = '{}/root.cert'.format(securityDir)
if not os.path.isfile(rootCertFile):
# Create root certificate
sh('ndnsec-keygen {}'.format(rootName)) # Installs a self-signed cert into the system
sh('ndnsec-cert-dump -i {} > {}'.format(rootName, rootCertFile))
# Create necessary certificates for each site
nodeSecurityFolder = '{}/security'.format(self.homeDir)
self.node.cmd('mkdir -p {}'.format(nodeSecurityFolder))
# Create temp folders for remote nodes on this machine (localhost) to store site.key file
# from RemoteNodes
if not os.path.exists(nodeSecurityFolder) and \
isinstance(self.node, RemoteMixin) and self.node.isRemote:
os.makedirs(nodeSecurityFolder)
shutil.copyfile('{}/root.cert'.format(securityDir),
'{}/root.cert'.format(nodeSecurityFolder))
# Create site certificate
siteName = '{}{}-site'.format(self.network, self.node.name)
siteKeyFile = '{}/site.keys'.format(nodeSecurityFolder)
siteCertFile = '{}/site.cert'.format(nodeSecurityFolder)
Nlsr.createKey(self.node, siteName, siteKeyFile)
# Copy siteKeyFile from remote for ndnsec-certgen
if isinstance(self.node, RemoteMixin) and self.node.isRemote:
login = 'mininet@{}'.format(self.node.server)
src = '{}:{}'.format(login, siteKeyFile)
dst = siteKeyFile
scp(src, dst)
# Root key is in root namespace, must sign site key and then install on host
sh('ndnsec-certgen -s {} -r {} > {}'.format(rootName, siteKeyFile, siteCertFile))
# Copy root.cert and site.cert from localhost to remote host
if isinstance(self.node, RemoteMixin) and self.node.isRemote:
login = 'mininet@{}'.format(self.node.server)
src = '{}/site.cert'.format(nodeSecurityFolder)
src2 = '{}/root.cert'.format(nodeSecurityFolder)
dst = '{}:/tmp/'.format(login)
scp(src, src2, dst)
self.node.cmd('mv /tmp/*.cert {}'.format(nodeSecurityFolder))
self.node.cmd('ndnsec-cert-install -f {}'.format(siteCertFile))
# Create and install operator certificate
opName = '{}/%C1.Operator/op'.format(siteName)
opKeyFile = '{}/op.keys'.format(nodeSecurityFolder)
opCertFile = '{}/op.cert'.format(nodeSecurityFolder)
Nlsr.createKey(self.node, opName, opKeyFile)
Nlsr.createCertificate(self.node, siteName, opKeyFile, opCertFile)
self.node.cmd('ndnsec-cert-install -f {}'.format(opCertFile))
# Create and install router certificate
routerName = '{}/%C1.Router/cs/{}'.format(siteName, self.node.name)
routerKeyFile = '{}/router.keys'.format(nodeSecurityFolder)
routerCertFile = '{}/router.cert'.format(nodeSecurityFolder)
Nlsr.createKey(self.node, routerName, routerKeyFile)
Nlsr.createCertificate(self.node, opName, routerKeyFile, routerCertFile)
self.node.cmd('ndnsec-cert-install -f {}'.format(routerCertFile))
def createConfigFile(self):
self.__editGeneralSection()
self.__editNeighborsSection()
self.__editHyperbolicSection()
self.__editFibSection()
self.__editAdvertisingSection()
self.__editSecuritySection()
def __editGeneralSection(self):
self.node.cmd('{} -s general.network -v {}'.format(self.infocmd, self.network))
self.node.cmd('{} -s general.site -v /{}-site'.format(self.infocmd, self.node.name))
self.node.cmd('{} -s general.router -v /%C1.Router/cs/{}'.format(self.infocmd, self.node.name))
self.node.cmd('{} -s general.state-dir -v {}/log'.format(self.infocmd, self.homeDir))
self.node.cmd('{} -s general.sync-protocol -v {}'.format(self.infocmd, self.sync))
def __editNeighborsSection(self):
self.node.cmd('{} -d neighbors.neighbor'.format(self.infocmd))
for intf in self.node.intfList():
link = intf.link
if not link:
continue
node1, node2 = link.intf1.node, link.intf2.node
# Todo: add some switch support
if isinstance(node1, Switch) or isinstance(node2, Switch):
continue
if node1 == self.node:
other = node2
ip = other.IP(str(link.intf2))
else:
other = node1
ip = other.IP(str(link.intf1))
linkCost = intf.params.get('delay', '10ms').replace('ms', '')
self.neighborIPs.append(ip)
self.node.cmd('{} -a neighbors.neighbor \
<<<\'name {}{}-site/%C1.Router/cs/{} face-uri {}://{}\n link-cost {}\''
.format(self.infocmd, self.network, other.name, other.name,
self.faceType, ip, linkCost))
def __editHyperbolicSection(self):
self.node.cmd('{} -s hyperbolic.state -v {}'.format(self.infocmd, self.hyperbolicState))
self.node.cmd('{} -s hyperbolic.radius -v {}'.format(self.infocmd, self.hyperRadius))
self.node.cmd('{} -s hyperbolic.angle -v {}'.format(self.infocmd, self.hyperAngle))
def __editFibSection(self):
self.node.cmd('{} -s fib.max-faces-per-prefix -v {}'.format(self.infocmd, self.nFaces))
def __editAdvertisingSection(self):
self.node.cmd('{} -d advertising.prefix'.format(self.infocmd))
self.node.cmd('{} -s advertising.prefix -v {}{}-site/{}'
.format(self.infocmd, self.network, self.node.name, self.node.name))
def __editSecuritySection(self):
self.node.cmd('{} -d security.cert-to-publish'.format(self.infocmd))
if not self.security:
self.node.cmd('{} -s security.validator.trust-anchor.type -v any'.format(self.infocmd))
self.node.cmd('{} -d security.validator.trust-anchor.file-name'.format(self.infocmd))
self.node.cmd('{} -s security.prefix-update-validator.trust-anchor.type -v any'.format(self.infocmd))
self.node.cmd('{} -d security.prefix-update-validator.trust-anchor.file-name'.format(self.infocmd))
else:
self.node.cmd('{} -s security.validator.trust-anchor.file-name -v security/root.cert'.format(self.infocmd))
self.node.cmd('{} -s security.prefix-update-validator.trust-anchor.file-name -v security/site.cert'.format(self.infocmd))
self.node.cmd('{} -p security.cert-to-publish -v security/site.cert'.format(self.infocmd))
self.node.cmd('{} -p security.cert-to-publish -v security/op.cert'.format(self.infocmd))
self.node.cmd('{} -p security.cert-to-publish -v security/router.cert'.format(self.infocmd))
File renamed without changes.
+107
View File
@@ -0,0 +1,107 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from itertools import cycle
from mininet.log import info
from minindn.helpers.nfdc import Nfdc
from minindn.helpers.ndnpingclient import NDNPingClient
class Experiment(object):
@staticmethod
def checkConvergence(ndn, hosts, convergenceTime, quit=False):
# Wait for convergence time period
info('Waiting {} seconds for convergence...\n'.format(convergenceTime))
time.sleep(convergenceTime)
info('...done\n')
# To check whether all the nodes of NLSR have converged
didNlsrConverge = True
# Checking for convergence
for host in hosts:
statusRouter = host.cmd('nfdc fib list | grep site/%C1.Router/cs/')
statusPrefix = host.cmd('nfdc fib list | grep ndn | grep site | grep -v Router')
didNodeConverge = True
for node in hosts:
# Node has its own router name in the fib list, but not name prefix
if (('/ndn/{}-site/%C1.Router/cs/{}'.format(node.name, node.name)) not in statusRouter or
host.name != node.name and ('/ndn/{}-site/{}'.format(node.name, node.name)) not in statusPrefix):
didNodeConverge = False
didNlsrConverge = False
host.cmd('echo {} > convergence-result &'.format(didNodeConverge))
if not didNlsrConverge:
info('NLSR has not converged. Exiting...\n')
if quit:
ndn.stop()
sys.exit(1)
else:
info('NLSR has converged successfully.\n')
return didNlsrConverge
@staticmethod
def setupPing(hosts, strategy):
for host in hosts:
host.cmd('mkdir -p ping-data')
Nfdc.setStrategy(host, '/ndn/', strategy)
host.cmd('ndnpingserver /ndn/{}-site/{} > ping-server &'.format(host.name, host.name))
@staticmethod
def startPctPings(net, nPings, pctTraffic=1.0):
nNodesToPing = int(round(len(net.hosts) * pctTraffic))
info('Each node will ping {} node(s)\n'.format(nNodesToPing))
# Temporarily store all the nodes being pinged by a particular node
nodesPingedList = []
pingedDict = {}
for host in net.hosts:
# Create a circular list
pool = cycle(net.hosts)
# Move iterator to current node
next(x for x in pool if host.name == x.name)
# Track number of nodes to ping scheduled for this node
nNodesScheduled = 0
while nNodesScheduled < nNodesToPing:
other = next(pool)
# Do not ping self
if host.name != other.name:
NDNPingClient.ping(host, other, nPings)
nodesPingedList.append(other)
# Always increment because in 100% case a node should not ping itself
nNodesScheduled = nNodesScheduled + 1
pingedDict[host] = nodesPingedList
nodesPingedList = []
return pingedDict
@@ -21,11 +21,10 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from igraph import *
from igraph import Graph
from mininet.log import info
class LinkInfo:
class LinkInfo(object):
"""
This class is used to encapsule link information (IP and interface names).
"""
@@ -36,8 +35,7 @@ class LinkInfo:
self.end_intf_name = end_intf_name
self.end_ip = end_ip
class IPRoutingHelper:
class IPRoutingHelper(object):
"""The routing helper allows to run IP-based evaluations with Mini-NDN. It configures static IP
routes to all nodes, which means that all nodes can reach all other nodes in the network
reachable, even when relaying is required.
@@ -79,9 +77,9 @@ class IPRoutingHelper:
mini_links = net.links
# Enabling IP forwaring on all nodes
info("Configure IP forwarding on all nodes\n")
info('Configure IP forwarding on all nodes\n')
for node in mini_nodes:
node.cmd("sysctl -w net.ipv4.ip_forward=1")
node.cmd('sysctl -w net.ipv4.ip_forward=1')
# Calculate igraph to calculate all shortest paths between nodes
node_names = [node.name for node in mini_nodes]
@@ -107,11 +105,11 @@ class IPRoutingHelper:
shortest_path = paths[0]
shortest_path_with_nodenames = []
for node in shortest_path:
shortest_path_with_nodenames.append(networkGraph.vs["name"][node])
shortest_path_with_nodenames.append(networkGraph.vs['name'][node])
named_paths.append(shortest_path_with_nodenames)
# Iterate over all paths and configure the routes using the "route add"
info("Configure routes on all nodes\n")
# Iterate over all paths and configure the routes using the 'route add'
info('Configure routes on all nodes\n')
for path in named_paths:
start_node = path[0]
end_node = path[-1]
@@ -125,12 +123,12 @@ class IPRoutingHelper:
addr = mini_end.intfs[intf].ip
if len(path) == 2:
# For direct connection, configure exit interface
info("[{}] route add -host {} dev {}\n".format(start_node, addr, start_intf))
mini_start.cmd("route add -host {} dev {}".format(addr, start_intf))
info('[{}] route add -host {} dev {}\n'.format(start_node, addr, start_intf))
mini_start.cmd('route add -host {} dev {}'.format(addr, start_intf))
elif len(path) > 2:
# For longer paths, configure next hop as gateway
gateway_ip = link_info.end_ip
info("[{}] route add -host {} dev {} gw {}\n"
info('[{}] route add -host {} dev {} gw {}\n'
.format(start_node, addr, start_intf, gateway_ip))
mini_start.cmd("route add -host {} dev {} gw {}"
mini_start.cmd('route add -host {} dev {} gw {}'
.format(addr, start_intf, gateway_ip))
@@ -1,5 +1,4 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#!/usr/bin/env python
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis
#
@@ -20,24 +19,121 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
# IMPORTANT! This feature is in highly experimental phase and may go several changes
# in future
'''
This module will compute link state, hyperbolic and geohyperbolic
routes and their costs from the given Mini-NDN topology
'''
import heapq
import math
from collections import defaultdict
from math import sin, cos, sinh, cosh, acos, acosh
import json
import operator
from collections import defaultdict
from mininet.log import info, debug, error
from mininet.log import info, debug, error, warn
from minindn.helpers.nfdc import Nfdc as nfdc
UNKNOWN_DISTANCE = -1
HYPERBOLIC_COST_ADJUSTMENT_FACTOR = 1000
class CalculateRoutes():
def dijkstra(graph, start, end, ignoredNode=None):
"""
Compute shortest path and cost from a given source to a destination
using Dijkstra algorithm
:param Graph graph: given network topology/graph
:param Start start: source node in a given network graph/topology
:end End end: destination node in a given network graph/topology
:param Node ignoredNode: node to ignore computing shortest path from
"""
queue = [(0, start, [])]
seen = set()
while True:
(cost, v, path) = heapq.heappop(queue)
if v not in seen:
path = path + [v]
seen.add(v)
if v == end:
debug("Distance from {} to {} is {}".format(start, end, cost))
return cost, path
for (_next, c) in graph[v].items():
if _next != ignoredNode: # Ignore path going via ignoreNode
heapq.heappush(queue, (cost + c, _next, path))
if not queue: # return if no path exist from source - destination except via ignoreNode
debug("Distance from {} to {} is {}".format(start, end, cost))
return cost, None
def calculateAngularDistance(angleVectorI, angleVectorJ):
"""
For hyperbolic/geohyperbolic routing algorithm, this function computes angular distance between
two nodes. A node can have two or more than two angular coordinates.
:param AngleVectorI angleVectorI: list of angular coordinate of a give node I
:param AngleVectorJ angleVectorJ: list of angular coordinate of a give node J
ref: https://en.wikipedia.org/wiki/N-sphere#Spherical_coordinates
"""
innerProduct = 0.0
if len(angleVectorI) != len(angleVectorJ):
error("Angle vector sizes do not match")
return UNKNOWN_DISTANCE
# Calculate x0 of the vectors
x0i = cos(angleVectorI[0])
x0j = cos(angleVectorJ[0])
# Calculate xn of the vectors
xni = sin(angleVectorI[len(angleVectorI) - 1])
xnj = sin(angleVectorJ[len(angleVectorJ) - 1])
# Do the aggregation of the (n-1) coordinates (if there is more than one angle)
# i.e contraction of all (n-1)-dimensional angular coordinates to one variable
for k in range(0, len(angleVectorI)-1):
xni *= sin(angleVectorI[k])
xnj *= sin(angleVectorJ[k])
innerProduct += (x0i * x0j) + (xni * xnj)
if len(angleVectorI) > 1:
for m in range(1, len(angleVectorI)):
# Calculate euclidean coordinates given the angles and assuming R_sphere = 1
xmi = cos(angleVectorI[m])
xmj = cos(angleVectorJ[m])
for l in range(0, m):
xmi *= sin(angleVectorI[l])
xmj *= sin(angleVectorJ[l])
innerProduct += xmi * xmj
# ArcCos of the inner product gives the angular distance
# between two points on a d-dimensional sphere
angularDist = acos(innerProduct)
debug("Angular distance from {} to {} is {}".format(angleVectorI, angleVectorJ, angularDist))
return angularDist
def getHyperbolicDistance(sourceNode, destNode):
"""
Return hyperbolic or geohyperbolic distance between two nodes. The distance is computed
on the basis of following algorithm/mathematics
ref: https://en.wikipedia.org/wiki/Hyperbolic_geometry
"""
r1 = [key for key in sourceNode][0]
r2 = [key for key in destNode][0]
zeta = 1.0
dtheta = calculateAngularDistance(sourceNode[r1], destNode[r2])
hyperbolicDistance = (1./zeta) * acosh(cosh(zeta * r1) * cosh(zeta * r2) -\
sinh(zeta * r1) * sinh(zeta * r2) * cos(dtheta))
debug("Distance from {} to {} is {}".format(sourceNode, destNode, hyperbolicDistance))
return hyperbolicDistance
class _CalculateRoutes(object):
"""
Creates a route calculation object, which is used to compute routes from a node to
every other nodes in a given topology topology using hyperbolic or geohyperbolic
@@ -51,14 +147,20 @@ class CalculateRoutes():
self.nodeDict = defaultdict(dict)
self.routingType = routingType
for host in netObj.hosts:
radius = float(host.params['params']['radius'])
angles = [float(x) for x in host.params['params']['angle'].split(',')]
if 'radius' in host.params['params']:
radius = float(host.params['params']['radius'])
else:
radius = 0.0
if 'angles' in host.params['params']:
angles = [float(x) for x in host.params['params']['angle'].split(',')]
else:
angles = 0.0
self.nodeDict[host.name][radius] = angles
for link in netObj.topo.links_conf:
linkDelay = int(link.linkDict['delay'].replace("ms", ""))
self.adjacenctMatrix[link.h1][link.h2] = linkDelay
self.adjacenctMatrix[link.h2][link.h1] = linkDelay
for link in netObj.topo.links(withInfo=True):
linkDelay = int(link[2]['delay'].replace("ms", ""))
self.adjacenctMatrix[link[0]][link[1]] = linkDelay
self.adjacenctMatrix[link[1]][link[0]] = linkDelay
def getNestedDictionary(self):
return defaultdict(self.getNestedDictionary)
@@ -169,96 +271,100 @@ class CalculateRoutes():
debug("Shortest Distance Matrix: {}".format(json.dumps(distanceMatrixViaNeighbor)))
return distanceMatrixViaNeighbor
def dijkstra(graph, start, end, ignoredNode = None):
class NdnRoutingHelper(object):
"""
Compute shortest path and cost from a given source to a destination
using Dijkstra algorithm
This module is a helper class which helps to create face and register routes
to NFD from a given node to all of its neighbors.
:param Graph graph: given network topology/graph
:param Start start: source node in a given network graph/topology
:end End end: destination node in a given network graph/topology
:param Node ignoredNode: node to ignore computing shortest path from
"""
queue = [(0, start, [])]
seen = set()
while True:
(cost, v, path) = heapq.heappop(queue)
if v not in seen:
path = path + [v]
seen.add(v)
if v == end:
debug("Distance from {} to {} is {}".format(start, end, cost))
return cost, path
for (_next, c) in graph[v].iteritems():
if _next != ignoredNode: # Ignore path going via ignoreNode
heapq.heappush(queue, (cost + c, _next, path))
if not queue: # return if no path exist from source - destination except via ignoreNode
debug("Distance from {} to {} is {}".format(start, end, cost))
return cost, None
def calculateAngularDistance(angleVectorI, angleVectorJ):
"""
For hyperbolic/geohyperbolic routing algorithm, this function computes angular distance between
two nodes. A node can have two or more than two angular coordinates.
:param AngleVectorI angleVectorI: list of angular coordinate of a give node I
:param AngleVectorJ angleVectorJ: list of angular coordinate of a give node J
ref: https://en.wikipedia.org/wiki/N-sphere#Spherical_coordinates
:param NetObject netObject: Mininet net object
:param FaceType faceType: UDP, Ethernet etc.
:param Routing routingType: (optional) Routing algorithm, link-state or hr etc
"""
innerProduct = 0.0
if len(angleVectorI) != len(angleVectorJ):
error("Angle vector sizes do not match")
return UNKNOWN_DISTANCE
def __init__(self, netObject, faceType=nfdc.PROTOCOL_UDP, routingType="link-state"):
self.net = netObject
self.faceType = faceType
self.routingType = routingType
self.routes = []
self.namePrefixes = {host_name.name: [] for host_name in self.net.hosts}
self.routeObject = _CalculateRoutes(self.net, self.routingType)
# Calculate x0 of the vectors
x0i = cos(angleVectorI[0])
x0j = cos(angleVectorJ[0])
def globalRoutingHelperHandler(self):
for host in self.net.hosts:
neighborIPs = self.getNeighbor(host)
self.createFaces(host, neighborIPs)
self.routeAdd(host, neighborIPs)
# Calculate xn of the vectors
xni = sin(angleVectorI[len(angleVectorI) - 1])
xnj = sin(angleVectorJ[len(angleVectorJ) - 1])
info('Processed all the routes to NFD\n')
# Do the aggregation of the (n-1) coordinates (if there is more than one angle)
# i.e contraction of all (n-1)-dimensional angular coordinates to one variable
for k in range(0, len(angleVectorI)-1):
xni *= sin(angleVectorI[k])
xnj *= sin(angleVectorJ[k])
def addOrigin(self, nodes, prefix):
"""
Add prefix/s as origin on node/s
innerProduct += (x0i * x0j) + (xni * xnj)
:param Prefix prefix: Prefix that is originated by node/s (as producer) for this prefix
:param Nodes nodes: List of nodes from net object
"""
for node in nodes:
self.namePrefixes[node.name] = prefix
if (len(angleVectorI) > 1):
for m in range(1, len(angleVectorI)):
# Calculate euclidean coordinates given the angles and assuming R_sphere = 1
xmi = cos(angleVectorI[m])
xmj = cos(angleVectorJ[m])
for l in range (0, m):
xmi *= sin(angleVectorI[l])
xmj *= sin(angleVectorJ[l])
def calculateNPossibleRoutes(self, nFaces=0):
"""
By default, calculates all possible routes i.e. routes via all the faces of a node.
pass nFaces if want to compute routes via n number of faces. e.g. 2. For larger topology
the computation might take huge amount of time.
innerProduct += xmi * xmj
:param int nFaces: (optional) number of faces to consider while computing routes. Default
i.e. nFaces = 0 will compute all possible routes
# ArcCos of the inner product gives the angular distance
# between two points on a d-dimensional sphere
angularDist = acos(innerProduct)
debug("Angular distance from {} to {} is {}".format(angleVectorI, angleVectorJ, angularDist))
return angularDist
"""
self.routes = self.routeObject.getRoutes(nFaces)
if self.routes:
self.globalRoutingHelperHandler()
else:
warn("Route computation failed\n")
def getHyperbolicDistance(sourceNode, destNode):
"""
Return hyperbolic or geohyperbolic distance between two nodes. The distance is computed
on the basis of following algorithm/mathematics
ref: https://en.wikipedia.org/wiki/Hyperbolic_geometry
"""
r1 = [key for key in sourceNode][0]
r2 = [key for key in destNode][0]
def calculateRoutes(self):
# Calculate shortest path for every node
self.calculateNPossibleRoutes(nFaces=1)
zeta = 1.0
dtheta = calculateAngularDistance(sourceNode[r1], destNode[r2])
hyperbolicDistance = (1./zeta) * acosh(cosh(zeta * r1) * cosh(zeta * r2) -\
sinh(zeta * r1) * sinh(zeta * r2) * cos(dtheta))
def createFaces(self, node, neighborIPs):
for ip in neighborIPs.values():
nfdc.createFace(node, ip, self.faceType)
debug("Distance from {} to {} is {}".format(sourceNode, destNode, hyperbolicDistance))
return hyperbolicDistance
def routeAdd(self, node, neighborIPs):
"""
Add route from a node to its neighbors for each prefix/s advertised by destination node
:param Node node: source node (Mininet net.host)
:param IP neighborIPs: IP addresses of neighbors
"""
neighbors = self.routes[node.name]
for route in neighbors:
destination = route[0]
cost = int(route[1])
nextHop = route[2]
defaultPrefix = "/ndn/{}-site/{}".format(destination, destination)
prefixes = [defaultPrefix] + self.namePrefixes[destination]
for prefix in prefixes:
# Register routes to all the available destination name prefix/s
nfdc.registerRoute(node, prefix, neighborIPs[nextHop], \
nfdc.PROTOCOL_UDP, cost=cost)
@staticmethod
def getNeighbor(node):
# Nodes to IP mapping
neighborIPs = defaultdict()
for intf in node.intfList():
link = intf.link
if link:
node1, node2 = link.intf1.node, link.intf2.node
if node1 == node:
other = node2
ip = other.IP(str(link.intf2))
else:
other = node1
ip = other.IP(str(link.intf1))
# Used later to create faces
neighborIPs[other.name] = ip
return neighborIPs
@@ -1,6 +1,6 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -23,21 +23,23 @@
import time
class NDNPingClient:
# Todo: convert to app
class NDNPingClient(object):
@staticmethod
def ping(source, dest, nPings=1, interval=None, timeout=None, starting_seq_num=None,
identifier=None, allow_stale_data=False, print_timestamp=True, sleepTime=0.2):
print("Scheduling ping(s) from {} to {}".format(source.name, dest.name))
# Use "&" to run in background and perform parallel pings
source.cmd("ndnping{1}{2}{3}{4}{5}{6}{7} /ndn/{0}-site/{0} >> ping-data/{0}.txt &"
print('Scheduling ping(s) from {} to {}'.format(source.name, dest.name))
# Use '&' to run in background and perform parallel pings
source.cmd('ndnping{1}{2}{3}{4}{5}{6}{7} /ndn/{0}-site/{0} >> ping-data/{0}.txt &'
.format(
dest,
" -c {}".format(nPings),
" -i {}".format(interval) if interval else "",
" -o {}".format(timeout) if timeout else "",
" -n {}".format(starting_seq_num) if starting_seq_num else "",
" -p {}".format(identifier) if identifier else "",
" -a" if allow_stale_data else "",
" -t" if print_timestamp else ""
' -c {}'.format(nPings),
' -i {}'.format(interval) if interval else '',
' -o {}'.format(timeout) if timeout else '',
' -n {}'.format(starting_seq_num) if starting_seq_num else '',
' -p {}'.format(identifier) if identifier else '',
' -a' if allow_stale_data else '',
' -t' if print_timestamp else ''
))
time.sleep(sleepTime)
time.sleep(sleepTime)
+26 -26
View File
@@ -21,65 +21,65 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import debug
from minindn.minindn import Minindn
SLEEP_TIME = 0.2
class Nfdc:
STRATEGY_ASF = "asf"
STRATEGY_BEST_ROUTE = "best-route"
STRATEGY_MULTICAST = "multicast"
STRATEGY_NCC = "ncc"
PROTOCOL_UDP = "udp"
PROTOCOL_TCP = "tcp"
PROTOCOL_ETHER = "ether"
class Nfdc(object):
STRATEGY_ASF = 'asf'
STRATEGY_BEST_ROUTE = 'best-route'
STRATEGY_MULTICAST = 'multicast'
STRATEGY_NCC = 'ncc'
PROTOCOL_UDP = 'udp'
PROTOCOL_TCP = 'tcp'
PROTOCOL_ETHER = 'ether'
@staticmethod
def registerRoute(node, namePrefix, remoteNodeAddress, protocol=PROTOCOL_UDP, origin=255,
cost=0, inheritFlag=True, captureFlag=False, expirationInMillis=None):
cmd = ("nfdc route add {} {}://{} origin {} cost {} {}{}").format(
cmd = ('nfdc route add {} {}://{} origin {} cost {} {}{}').format(
namePrefix,
protocol,
remoteNodeAddress,
origin,
cost,
"no-inherit " if not inheritFlag else "",
"capture " if captureFlag else "",
"expires {}".format(expirationInMillis) if expirationInMillis else ""
'no-inherit ' if not inheritFlag else '',
'capture ' if captureFlag else '',
'expires {}'.format(expirationInMillis) if expirationInMillis else ''
)
debug(node.cmd(cmd))
time.sleep(SLEEP_TIME)
Minindn.sleep(SLEEP_TIME)
@staticmethod
def unregisterRoute(node, namePrefix, remoteNodeAddress, origin=255):
cmd = "nfdc route remove {} {} {}".format(namePrefix, remoteNodeAddress, origin)
cmd = 'nfdc route remove {} {} {}'.format(namePrefix, remoteNodeAddress, origin)
debug(node.cmd(cmd))
time.sleep(SLEEP_TIME)
Minindn.sleep(SLEEP_TIME)
@staticmethod
def createFace(node, remoteNodeAddress, protocol="udp", isPermanent=False):
cmd = ("nfdc face create {}://{} {}".format(
def createFace(node, remoteNodeAddress, protocol='udp', isPermanent=False):
cmd = ('nfdc face create {}://{} {}'.format(
protocol,
remoteNodeAddress,
"permanent" if isPermanent else "persistent"
'permanent' if isPermanent else 'persistent'
))
debug(node.cmd(cmd))
time.sleep(SLEEP_TIME)
Minindn.sleep(SLEEP_TIME)
@staticmethod
def destroyFace(node, remoteNodeAddress, protocol="udp"):
debug(node.cmd("nfdc face destroy {}://{}".format(protocol, remoteNodeAddress)))
time.sleep(SLEEP_TIME)
def destroyFace(node, remoteNodeAddress, protocol='udp'):
debug(node.cmd('nfdc face destroy {}://{}'.format(protocol, remoteNodeAddress)))
Minindn.sleep(SLEEP_TIME)
@staticmethod
def setStrategy(node, namePrefix, strategy):
cmd = "nfdc strategy set {} ndn:/localhost/nfd/strategy/{}".format(namePrefix, strategy)
cmd = 'nfdc strategy set {} ndn:/localhost/nfd/strategy/{}'.format(namePrefix, strategy)
debug(node.cmd(cmd))
time.sleep(SLEEP_TIME)
Minindn.sleep(SLEEP_TIME)
@staticmethod
def unsetStrategy(node, namePrefix):
debug(node.cmd("nfdc strategy unset {}".format(namePrefix)))
time.sleep(SLEEP_TIME)
Minindn.sleep(SLEEP_TIME)
@@ -1,6 +1,6 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -23,27 +23,26 @@
import time
from subprocess import call
from threading import Timer
class ProcessMonitor:
class ProcessMonitor(object):
def __init__(self, processId, processName, outputDir, interval=1):
self._processId = processId.strip()
self._processName = processName
self._statFile = "/proc/{}/stat".format(self._processId)
self._logFile = "{}/{}-{}-stat.txt".format(outputDir, self._processName, self._processId)
self._statFile = '/proc/{}/stat'.format(self._processId)
self._logFile = '{}/{}-{}-stat.txt'.format(outputDir, self._processName, self._processId)
self._interval = interval
def _recordStats(self):
try:
with open(self._statFile, "r") as stat:
with open(self._statFile, 'r') as stat:
currentTime = int(time.time())
with open(self._logFile, "a") as log:
with open(self._logFile, 'a') as log:
for line in stat:
log.write("{} {}".format(currentTime, line))
log.write('{} {}'.format(currentTime, line))
except IOError as e:
print "I/O error({0}): {1}".format(e.errno, e.strerror)
print "No process with PID={}".format(self._processId)
print('I/O error({0}): {1}'.format(e.errno, e.strerror))
print('No process with PID={}'.format(self._processId))
return
self.start() # Reschedule event
+213
View File
@@ -0,0 +1,213 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import argparse
import sys
import time
import os
import configparser
from subprocess import call, check_output
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.link import TCLink
from mininet.node import Switch
from mininet.util import ipStr, ipParse
from mininet.log import info, error
class Minindn(object):
""" This class provides the following features to the user:
1) Wrapper around Mininet object with option to pass topology directly
1.1) Users can pass custom argument parser to extend the default on here
2) Parses the topology file given via command line if user does not pass a topology object
3) Provides way to stop Mini-NDN via stop
3.1) Applications register their clean up function with this class
4) Sets IPs on neighbors for connectivity required in a switch-less topology
5) Some other utility functions
"""
ndnSecurityDisabled = False
def __init__(self, parser=argparse.ArgumentParser(), topo=None, topoFile=None, **mininetParams):
"""Create MiniNDN object
parser: Parent parser of Mini-NDN parser
topo: Mininet topo object (optional)
topoFile: Mininet topology file location (optional)
mininetParams: Any params to pass to Mininet
"""
self.parser = Minindn.parseArgs(parser)
self.args = self.parser.parse_args()
self.workDir = self.args.workDir
self.resultDir = self.args.resultDir
if not topoFile:
# Args has default topology if none specified
self.topoFile = self.args.topoFile
else:
self.topoFile = topoFile
if topo is None:
try:
info('Using topology file {}\n'.format(self.topoFile))
self.topo = self.processTopo(self.topoFile)
except configparser.NoSectionError as e:
info('Error reading config file: {}\n'.format(e))
sys.exit(1)
else:
self.topo = topo
self.net = Mininet(topo=self.topo, link=TCLink, **mininetParams)
for host in self.net.hosts:
if 'params' not in host.params:
host.params['params'] = {}
homeDir = '{}/{}'.format(self.workDir, host.name)
host.params['params']['homeDir'] = homeDir
host.cmd('mkdir -p {}'.format(homeDir))
host.cmd('export HOME={} && cd ~'.format(homeDir))
self.cleanups = []
if not self.net.switches:
self.ethernetPairConnectivity()
try:
Minindn.ndnSecurityDisabled = '/dummy/KEY/-%9C%28r%B8%AA%3B%60' in \
check_output('ndnsec-get-default -k'.split()). \
decode('utf-8').split('\n')
info('Dummy key chain patch is installed in ndn-cxx. Security will be disabled.\n')
except:
pass
@staticmethod
def parseArgs(parent):
parser = argparse.ArgumentParser(prog='minindn', parents=[parent], add_help=False)
# nargs='?' required here since optional argument
parser.add_argument('topoFile', nargs='?', default='/usr/local/etc/mini-ndn/default-topology.conf',
help='If no template_file is given, topologies/default-topology.conf will be used.')
parser.add_argument('--work-dir', action='store', dest='workDir', default='/tmp/minindn',
help='Specify the working directory; default is /tmp/minindn')
parser.add_argument('--result-dir', action='store', dest='resultDir', default=None,
help='Specify the full path destination folder where experiment results will be moved')
return parser
def ethernetPairConnectivity(self):
ndnNetBase = '10.0.0.0'
interfaces = []
for host in self.net.hosts:
for intf in host.intfList():
link = intf.link
node1, node2 = link.intf1.node, link.intf2.node
if isinstance(node1, Switch) or isinstance(node2, Switch):
continue
if link.intf1 not in interfaces and link.intf2 not in interfaces:
interfaces.append(link.intf1)
interfaces.append(link.intf2)
node1.setIP(ipStr(ipParse(ndnNetBase) + 1) + '/30', intf=link.intf1)
node2.setIP(ipStr(ipParse(ndnNetBase) + 2) + '/30', intf=link.intf2)
ndnNetBase = ipStr(ipParse(ndnNetBase) + 4)
@staticmethod
def processTopo(topoFile):
config = configparser.ConfigParser(delimiters=' ')
config.read(topoFile)
topo = Topo()
items = config.items('nodes')
for item in items:
name = item[0].split(':')[0]
params = {}
for param in item[1].split(' '):
if param == '_':
continue
params[param.split('=')[0]] = param.split('=')[1]
topo.addHost(name, params=params)
try:
items = config.items('switches')
for item in items:
name = item[0].split(':')[0]
topo.addSwitch(name)
except configparser.NoSectionError:
# Switches are optional
pass
items = config.items('links')
for item in items:
link = item[0].split(':')
params = {}
for param in item[1].split(' '):
key = param.split('=')[0]
value = param.split('=')[1]
if key in ['bw', 'jitter', 'max_queue_size']:
value = int(value)
if key == 'loss':
value = float(value)
params[key] = value
topo.addLink(link[0], link[1], **params)
return topo
def start(self):
self.net.start()
time.sleep(3)
def stop(self):
for cleanup in self.cleanups:
cleanup()
self.net.stop()
@staticmethod
def cleanUp():
devnull = open(os.devnull, 'w')
call('nfd-stop', stdout=devnull, stderr=devnull)
call('mn --clean'.split(), stdout=devnull, stderr=devnull)
@staticmethod
def verifyDependencies():
"""Prevent MiniNDN from running without necessary dependencies"""
dependencies = ['nfd', 'nlsr', 'infoedit', 'ndnping', 'ndnpingserver']
devnull = open(os.devnull, 'w')
# Checks that each program is in the system path
for program in dependencies:
if call(['which', program], stdout=devnull):
error('{} is missing from the system path! Exiting...\n'.format(program))
sys.exit(1)
devnull.close()
@staticmethod
def sleep(seconds):
# sleep is not required if ndn-cxx is using in-memory keychain
if not Minindn.ndnSecurityDisabled:
time.sleep(seconds)
+31 -36
View File
@@ -1,6 +1,6 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
@@ -21,13 +21,13 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from subprocess import call
from mininet.cli import CLI
import sys
from os.path import isfile
from subprocess import call
from mininet.cli import CLI
sshbase = [ 'ssh', '-q', '-t', '-i/home/mininet/.ssh/id_rsa' ]
scpbase = [ 'scp', '-i', '/home/mininet/.ssh/id_rsa' ]
sshbase = ['ssh', '-q', '-t', '-i/home/mininet/.ssh/id_rsa']
scpbase = ['scp', '-i', '/home/mininet/.ssh/id_rsa']
devnull = open('/dev/null', 'w')
def ssh(login, cmd):
@@ -42,41 +42,36 @@ def scp(*args):
call(rcmd, stdout=devnull, stderr=devnull)
def copyExistentFile(node, fileList, destination):
for file in fileList:
if isfile(file):
node.cmd("cp {} {}".format(file, destination))
for f in fileList:
if isfile(f):
node.cmd('cp {} {}'.format(f, destination))
break
if not isfile(destination):
fileName = destination.split("/")[-1]
raise IOError("{} not found in expected directory.".format(fileName))
fileName = destination.split('/')[-1]
raise IOError('{} not found in expected directory.'.format(fileName))
def popenGetEnv(node, envDict=None):
env = {}
homeDir = node.params['params']['homeDir']
printenv = node.popen('printenv'.split(), cwd=homeDir).communicate()[0].decode('utf-8')
for var in printenv.split('\n'):
if var == '':
break
p = var.split('=')
env[p[0]] = p[1]
env['HOME'] = homeDir
if envDict is not None:
for key, value in envDict.items():
env[key] = str(value)
return env
def getPopen(host, cmd, envDict=None, **params):
return host.popen(cmd, cwd=host.params['params']['homeDir'],
env=popenGetEnv(host, envDict), **params)
class MiniNDNCLI(CLI):
prompt = 'mini-ndn> '
def __init__(self, mininet, stdin=sys.stdin, script=None):
CLI.__init__(self, mininet, stdin=sys.stdin, script=None)
class ProgramOptions:
def __init__(self):
self.ctime = 60
self.experimentName = None
self.nFaces = 3
self.templateFile = "minindn.conf"
self.routingType = "link-state"
self.isNlsrEnabled = True
self.isCliEnabled = True
self.nlsrSecurity = False
self.nPings = 300
self.testbed = False
self.workDir = "/tmp/minindn"
self.resultDir = None
self.pctTraffic = 1.0
self.cluster = None
self.servers = None
self.guided = None
self.placer = None
self.tunnelType = None
self.faceType = "udp"
self.arguments = None
self.csSize = 65536
self.strategy = "best-route"
CLI.__init__(self, mininet, stdin, script)
-24
View File
@@ -1,24 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import experiment_manager as ExperimentManager
-127
View File
@@ -1,127 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
# IMPORTANT! This feature is in highly experimental phase and may go several changes
# in future
from mininet.log import info
from ndn.apps.nfdc import Nfdc as nfdc
from collections import defaultdict
from ndn.apps.calculate_routing import CalculateRoutes
from mininet.log import warn
class GlobalRoutingHelper():
"""
This module is a helper class which helps to create face and register routes
to NFD from a given node to all of its neighbors.
:param NetObject netObject: Mininet net object
:param FaceType faceType: UDP, Ethernet etc.
:param Routing routingType: (optional) Routing algorithm, link-state or hr etc
"""
def __init__(self, netObject, faceType=nfdc.PROTOCOL_UDP, routingType="link-state"):
self.net = netObject
self.faceType = faceType
self.routingType = routingType
self.routes = []
self.namePrefixes = {host_name.name: [] for host_name in self.net.hosts}
self.routeObject = CalculateRoutes(self.net, self.routingType)
def globalRoutingHelperHandler(self):
for host in self.net.hosts:
neighborIPs = self.getNeighbor(host)
self.createFaces(host, neighborIPs)
self.routeAdd(host, neighborIPs)
info('Processed all the routes to NFD\n')
def addOrigin(self, nodes, prefix):
"""
Add prefix/s as origin on node/s
:param Prefix prefix: Prefix that is originated by node/s (as producer) for this prefix
:param Nodes nodes: List of nodes from net object
"""
for node in nodes:
self.namePrefixes[node.name] = prefix
def calculateNPossibleRoutes(self, nFaces=0):
"""
By default, calculates all possible routes i.e. routes via all the faces of a node.
pass nFaces if want to compute routes via n number of faces. e.g. 2. For larger topology
the computation might take huge amount of time.
:param int nFaces: (optional) number of faces to consider while computing routes. Default
i.e. nFaces = 0 will compute all possible routes
"""
self.routes = self.routeObject.getRoutes(nFaces)
if self.routes:
self.globalRoutingHelperHandler()
else:
warn("Route computation failed\n")
def calculateRoutes(self):
# Calculate shortest path for every node
calculateNPossibleRoutes(self, nFaces=1)
def createFaces(self, node, neighborIPs):
for ip in neighborIPs.values():
nfdc.createFace(node, ip, self.faceType)
def routeAdd(self, node, neighborIPs):
"""
Add route from a node to its neighbors for each prefix/s advertised by destination node
:param Node node: source node (Mininet net.host)
:param IP neighborIPs: IP addresses of neighbors
"""
neighbors = self.routes[node.name]
for route in neighbors:
destination = route[0]
cost = int(route[1])
nextHop = route[2]
defaultPrefix = "/ndn/{}-site/{}".format(destination, destination)
prefixes = [defaultPrefix] + self.namePrefixes[destination]
for prefix in prefixes:
# Register routes to all the available destination name prefix/s
nfdc.registerRoute(node, prefix, neighborIPs[nextHop], \
nfdc.PROTOCOL_UDP, cost=cost)
@staticmethod
def getNeighbor(node):
# Nodes to IP mapping
neighborIPs = defaultdict()
for intf in node.intfList():
link = intf.link
if link:
node1, node2 = link.intf1.node, link.intf2.node
if node1 == node:
other = node2
ip = other.IP(str(link.intf2))
else:
other = node1
ip = other.IP(str(link.intf1))
# Used later to create faces
neighborIPs[other.name] = ip
return neighborIPs
-242
View File
@@ -1,242 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from mininet.clean import sh
from mininet.examples.cluster import RemoteMixin
from mininet.log import info
from ndn.ndn_application import NdnApplication
from ndn.util import ssh, scp, copyExistentFile
from ndn.apps.nfdc import Nfdc
import shutil
import os
import textwrap
from subprocess import call
import time
NETWORK="/ndn/"
class Nlsr(NdnApplication):
def __init__(self, node, options):
NdnApplication.__init__(self, node)
self.config = NlsrConfigGenerator(node, options)
self.node = node
self.routerName = "/{}C1.Router/cs/{}".format('%', node.name)
self.confFile = "{}/nlsr.conf".format(node.homeFolder)
# Make directory for log file
self.logDir = "{}/log".format(node.homeFolder)
self.node.cmd("mkdir {}".format(self.logDir))
def start(self, sleepTime = 1):
self.node.cmd("export NDN_LOG=nlsr.*={}".format(self.node.params["params"].get("nlsr-log-level", "DEBUG")))
NdnApplication.start(self, "nlsr -f {} > log/nlsr.log 2>&1 &".format(self.confFile))
time.sleep(sleepTime)
def createFaces(self):
for ip in self.config.neighborIPs:
Nfdc.createFace(self.node, ip, self.config.faceType, isPermanent=True)
@staticmethod
def createKey(host, name, outputFile):
host.cmd("ndnsec-keygen {} > {}".format(name, outputFile))
@staticmethod
def createCertificate(host, signer, keyFile, outputFile):
host.cmd("ndnsec-certgen -s {} -r {} > {}".format(signer, keyFile, outputFile))
@staticmethod
def createKeysAndCertificates(net, workDir):
securityDir = "{}/security".format(workDir)
if not os.path.exists(securityDir):
os.mkdir(securityDir)
# Create root certificate
rootName = NETWORK
sh("ndnsec-keygen {}".format(rootName)) # Installs a self-signed cert into the system
sh("ndnsec-cert-dump -i {} > {}/root.cert".format(rootName, securityDir))
# Create necessary certificates for each site
for host in net.hosts:
nodeSecurityFolder = "{}/security".format(host.homeFolder)
host.cmd("mkdir -p %s" % nodeSecurityFolder)
# Create temp folders for remote nodes on this machine (localhost) to store site.key file
# from RemoteNodes
if not os.path.exists(nodeSecurityFolder) and isinstance(host, RemoteMixin) and host.isRemote:
os.makedirs(nodeSecurityFolder)
shutil.copyfile("{}/root.cert".format(securityDir), "{}/root.cert".format(nodeSecurityFolder))
# Create site certificate
siteName = "{}{}-site".format(NETWORK, host.name)
siteKeyFile = "{}/site.keys".format(nodeSecurityFolder)
siteCertFile = "{}/site.cert".format(nodeSecurityFolder)
Nlsr.createKey(host, siteName, siteKeyFile)
# Copy siteKeyFile from remote for ndnsec-certgen
if isinstance(host, RemoteMixin) and host.isRemote:
login = "mininet@{}".format(host.server)
src = "{}:{}".format(login, siteKeyFile)
dst = siteKeyFile
scp(src, dst)
# Root key is in root namespace, must sign site key and then install on host
sh("ndnsec-certgen -s {} -r {} > {}".format(rootName, siteKeyFile, siteCertFile))
# Copy root.cert and site.cert from localhost to remote host
if isinstance(host, RemoteMixin) and host.isRemote:
login = "mininet@{}".format(host.server)
src = "{}/site.cert".format(nodeSecurityFolder)
src2 = "{}/root.cert".format(nodeSecurityFolder)
dst = "{}:/tmp/".format(login)
scp(src, src2, dst)
host.cmd("mv /tmp/*.cert {}".format(nodeSecurityFolder))
host.cmd("ndnsec-cert-install -f {}".format(siteCertFile))
# Create and install operator certificate
opName = "{}/%C1.Operator/op".format(siteName)
opKeyFile = "{}/op.keys".format(nodeSecurityFolder)
opCertFile = "{}/op.cert".format(nodeSecurityFolder)
Nlsr.createKey(host, opName, opKeyFile)
Nlsr.createCertificate(host, siteName, opKeyFile, opCertFile)
host.cmd("ndnsec-cert-install -f {}".format(opCertFile))
# Create and install router certificate
routerName = "{}/%C1.Router/cs/{}".format(siteName, host.name)
routerKeyFile = "{}/router.keys".format(nodeSecurityFolder)
routerCertFile = "{}/router.cert".format(nodeSecurityFolder)
Nlsr.createKey(host, routerName, routerKeyFile)
Nlsr.createCertificate(host, opName, routerKeyFile, routerCertFile)
host.cmd("ndnsec-cert-install -f {}".format(routerCertFile))
class NlsrConfigGenerator:
ROUTING_LINK_STATE = "ls"
ROUTING_HYPERBOLIC = "hr"
def __init__(self, node, options):
self.node = node
self.isSecurityEnabled = options.nlsrSecurity
self.faceType = options.faceType
self.infocmd = "infoedit -f nlsr.conf"
parameters = node.params["params"]
self.nFaces = options.nFaces
if options.routingType == "hr":
self.hyperbolicState = "on"
elif options.routingType == "dry":
self.hyperbolicState = "dry-run"
else:
self.hyperbolicState = "off"
self.hyperRadius = parameters.get("radius", 0.0)
self.hyperAngle = parameters.get("angle", 0.0)
if ((self.hyperbolicState == "on" or self.hyperbolicState == "dry-run") and
(self.hyperRadius == 0.0 or self.hyperAngle == 0.0)):
info('Hyperbolic coordinates in topology file are either missing or misconfigured.')
info('Check that each node has one radius value and one or two angle value(s).')
sys.exit(1)
self.neighborIPs = []
possibleConfPaths = ["/usr/local/etc/ndn/nlsr.conf.sample", "/etc/ndn/nlsr.conf.sample"]
copyExistentFile(node, possibleConfPaths, "{}/nlsr.conf".format(self.node.homeFolder))
self.createConfigFile()
def createConfigFile(self):
self.__editGeneralSection()
self.__editNeighborsSection()
self.__editHyperbolicSection()
self.__editFibSection()
self.__editAdvertisingSection()
self.__editSecuritySection()
def __editGeneralSection(self):
self.node.cmd("{} -s general.network -v {}".format(self.infocmd, NETWORK))
self.node.cmd("{} -s general.site -v /{}-site".format(self.infocmd, self.node.name))
self.node.cmd("{} -s general.router -v /%C1.Router/cs/{}".format(self.infocmd, self.node.name))
self.node.cmd("{} -s general.state-dir -v {}/log".format(self.infocmd, self.node.homeFolder))
def __editNeighborsSection(self):
self.node.cmd("{} -d neighbors.neighbor".format(self.infocmd))
for intf in self.node.intfList():
link = intf.link
if link:
node1, node2 = link.intf1.node, link.intf2.node
if node1 == self.node:
other = node2
ip = other.IP(str(link.intf2))
else:
other = node1
ip = other.IP(str(link.intf1))
linkCost = intf.params.get("delay", "10ms").replace("ms", "")
Nfdc.createFace(self.node, ip, self.faceType, isPermanent=True)
self.neighborIPs.append(ip)
self.node.cmd("{} -a neighbors.neighbor \
<<<\'name {}{}-site/%C1.Router/cs/{} face-uri {}://{}\n link-cost {}\'"
.format(self.infocmd, NETWORK, other.name, other.name, self.faceType, ip, linkCost))
def __editHyperbolicSection(self):
self.node.cmd("{} -s hyperbolic.state -v {}".format(self.infocmd, self.hyperbolicState))
self.node.cmd("{} -s hyperbolic.radius -v {}".format(self.infocmd, self.hyperRadius))
self.node.cmd("{} -s hyperbolic.angle -v {}".format(self.infocmd, self.hyperAngle))
def __editFibSection(self):
self.node.cmd("{} -s fib.max-faces-per-prefix -v {}".format(self.infocmd, self.nFaces))
def __editAdvertisingSection(self):
self.node.cmd("{} -d advertising.prefix".format(self.infocmd))
self.node.cmd("{} -s advertising.prefix -v {}{}-site/{}"
.format(self.infocmd, NETWORK, self.node.name, self.node.name))
def __editSecuritySection(self):
self.node.cmd("{} -d security.cert-to-publish".format(self.infocmd))
if self.isSecurityEnabled is False:
self.node.cmd("{} -s security.validator.trust-anchor.type -v any".format(self.infocmd))
self.node.cmd("{} -d security.validator.trust-anchor.file-name".format(self.infocmd))
self.node.cmd("{} -s security.prefix-update-validator.trust-anchor.type -v any".format(self.infocmd))
self.node.cmd("{} -d security.prefix-update-validator.trust-anchor.file-name".format(self.infocmd))
else:
self.node.cmd("{} -s security.validator.trust-anchor.file-name -v security/root.cert".format(self.infocmd))
self.node.cmd("{} -s security.prefix-update-validator.trust-anchor.file-name -v security/site.cert".format(self.infocmd))
self.node.cmd("{} -p security.cert-to-publish -v security/site.cert".format(self.infocmd))
self.node.cmd("{} -p security.cert-to-publish -v security/op.cert".format(self.infocmd))
self.node.cmd("{} -p security.cert-to-publish -v security/router.cert".format(self.infocmd))
-206
View File
@@ -1,206 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
#
# This file incorporates work covered by the following copyright and
# permission notice:
#
# Mininet 2.2.1 License
#
# Copyright (c) 2013-2015 Open Networking Laboratory
# Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
# The Leland Stanford Junior University
#
# Original authors: Bob Lantz and Brandon Heller
#
# We are making Mininet available for public use and benefit with the
# expectation that others will use, modify and enhance the Software and
# contribute those enhancements back to the community. However, since we
# would like to make the Software available for broadest use, with as few
# restrictions as possible permission is hereby granted, free of charge, to
# any person obtaining a copy of this Software to deal in the Software
# under the copyrights without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# The name and trademarks of copyright holder(s) may NOT be used in
# advertising or publicity pertaining to the Software or any derivatives
# without specific, written prior permission.
import ConfigParser, re
import shlex
import sys
from mininet.log import error
class confNDNHost():
def __init__(self, name, app='', params='', cpu=None, cores=None, cache=None):
self.name = name
self.app = app
self.params = params
self.cpu = cpu
self.cores = cores
self.cache = cache
def __repr__(self):
return " Name: {} App: {} Params: {} CPU: {} Cores: {} Cores: {} Cache: {}" \
.format(self.name, self.app, self.params, self.cpu, self.cores, self.cache)
class confNdnSwitch:
def __init__(self, name):
self.name = name
class confNDNLink():
def __init__(self,h1,h2,linkDict=None):
self.h1 = h1
self.h2 = h2
self.linkDict = linkDict
def __repr__(self):
return "h1: {} h2: {} params: {}".format(self.h1, self.h2, self.linkDict)
def parse_hosts(conf_arq):
'Parse hosts section from the conf file.'
config = ConfigParser.RawConfigParser()
config.read(conf_arq)
hosts = []
items = config.items('nodes')
# makes a first-pass read to hosts section to find empty host sections
coordinates = []
for item in items:
name = item[0]
rest = item[1].split()
# check for the duplicate coordinates
if "radius" in item[1]:
if item[1] in coordinates:
error("FATAL: Duplicate Coordinate, \"{}\" used by multiple nodes\n" \
.format(item[1]))
sys.exit(1)
else:
coordinates.append(item[1])
if len(rest) == 0:
config.set('nodes', name, '_')
# updates 'items' list
items = config.items('nodes')
# makes a second-pass read to hosts section to properly add hosts
for item in items:
name = item[0]
rest = shlex.split(item[1])
uris = rest
params = {}
cpu = None
cores = None
cache = None
for uri in uris:
if re.match("cpu",uri):
cpu = float(uri.split('=')[1])
elif re.match("cores",uri):
cores = uri.split('=')[1]
elif re.match("cache",uri):
cache = uri.split('=')[1]
elif re.match("mem",uri):
mem = uri.split('=')[1]
elif re.match("app",uri):
app = uri.split('=')[1]
elif re.match("_", uri):
app = ""
else:
params[uri.split('=')[0]] = uri.split('=')[1]
hosts.append(confNDNHost(name, app, params, cpu, cores, cache))
return hosts
def parse_switches(conf_arq):
'Parse switches section from the conf file.'
config = ConfigParser.RawConfigParser()
config.read(conf_arq)
switches = []
try:
items = config.items('switches')
except ConfigParser.NoSectionError:
return switches
for item in items:
name = item[0]
switches.append(confNdnSwitch(name))
return switches
def parse_links(conf_arq):
'Parse links section from the conf file.'
arq = open(conf_arq, 'r')
links = []
linkSectionFlag = False
for line in arq:
if linkSectionFlag:
args = line.split()
# checks for non-empty line
if len(args) == 0:
continue
h1, h2 = args.pop(0).split(':')
link_dict = {}
for arg in args:
arg_name, arg_value = arg.split('=')
key = arg_name
value = arg_value
if key in ['bw','jitter','max_queue_size']:
value = int(value)
if key in ['loss']:
value = float(value)
link_dict[key] = value
links.append(confNDNLink(h1,h2,link_dict))
elif line == "[links]\n":
linkSectionFlag = True
return links
-97
View File
@@ -1,97 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import os
class _ExperimentManager:
class Error(Exception):
def __init__(self, what):
self.what = what
def __str__(self):
return repr(self.what)
instance = None
def __init__(self):
self.experiments = {}
def loadModules(self):
currentDir = os.path.dirname(__file__)
experimentDir = "{}/{}".format(currentDir, "experiments")
experimentModule = "ndn.experiments"
# Import and register experiments
for root, dirs, files in os.walk(experimentDir):
for filename in files:
if filename.endswith(".py") and filename != "__init__.py":
module = filename.replace(".py", "")
subdir = os.path.basename(root)
if subdir == "experiments":
__import__("{}.{}".format(experimentModule, module))
else:
__import__("{}.{}.{}".format(experimentModule, subdir, module))
def register(self, name, experimentClass):
if name not in self.experiments:
self.experiments[name] = experimentClass
else:
raise _ExperimentManager.Error("Experiment '{}' has already been registered".format(name))
def create(self, name, args):
if name in self.experiments:
return self.experiments[name](args)
else:
return None
def __getInstance():
if _ExperimentManager.instance is None:
_ExperimentManager.instance = _ExperimentManager()
_ExperimentManager.instance.loadModules()
return _ExperimentManager.instance
def register(name, experimentClass):
manager = __getInstance()
manager.register(name, experimentClass)
def create(name, args):
manager = __getInstance()
return manager.create(name, args)
def getExperimentNames():
manager = __getInstance()
experimentNames = []
for key in manager.experiments:
experimentNames.append(key)
return experimentNames
def addExperimentArgs(parser):
# Find all experiment command line arguments and parse them.
manager = __getInstance()
for name in manager.experiments:
if hasattr(manager.experiments[name], "parseArguments"):
manager.experiments[name].parseArguments(parser)
-172
View File
@@ -1,172 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from itertools import cycle
from mininet.log import info
from ndn import ExperimentManager
from ndn.apps.nfdc import Nfdc
from ndn.apps.nlsr import Nlsr, NlsrConfigGenerator
from ndn.apps.ndn_ping_client import NDNPingClient
class Experiment:
def __init__(self, args):
self.net = args["net"]
self.options = args["options"]
# Used to restart pings on the recovered node if any
self.pingedDict = {}
def afterNfdStart(self):
pass
def start(self):
self.afterNfdStart()
if self.options.isNlsrEnabled is True:
self.startNlsr()
self.setup()
self.run()
def setup(self):
for host in self.net.hosts:
# Set strategy
Nfdc.setStrategy(host, "/ndn/", self.options.strategy)
# Start ping server
host.cmd("ndnpingserver /ndn/{}-site/{} > ping-server &".format(host.name, host.name))
# Create folder to store ping data
host.cmd("mkdir ping-data")
def startNlsr(self, checkConvergence = True):
# NLSR Security
if self.options.nlsrSecurity is True:
Nlsr.createKeysAndCertificates(self.net, self.options.workDir)
# NLSR initialization
info('Starting NLSR on nodes\n')
for host in self.net.hosts:
host.nlsr = Nlsr(host, self.options)
host.nlsr.start()
for host in self.net.hosts:
nlsrStatus = host.cmd("ps -g | grep 'nlsr -f {}/[n]lsr.conf'".format(host.homeFolder))
if not host.nlsr.isRunning or not nlsrStatus:
print("NLSR on host {} is not running. Printing log file and exiting...".format(host.name))
print(host.cmd("tail {}/log/nlsr.log".format(host.homeFolder)))
self.net.stop()
sys.exit(1)
if checkConvergence:
self.checkConvergence()
def checkConvergence(self, convergenceTime = None):
if convergenceTime is None:
convergenceTime = self.options.ctime
# Wait for convergence time period
print "Waiting " + str(convergenceTime) + " seconds for convergence..."
time.sleep(convergenceTime)
print "...done"
# To check whether all the nodes of NLSR have converged
didNlsrConverge = True
# Checking for convergence
for host in self.net.hosts:
statusRouter = host.cmd("nfdc fib list | grep site/%C1.Router/cs/")
statusPrefix = host.cmd("nfdc fib list | grep ndn | grep site | grep -v Router")
didNodeConverge = True
for node in self.net.hosts:
# Node has its own router name in the fib list, but not name prefix
if ( ("/ndn/{}-site/%C1.Router/cs/{}".format(node.name, node.name)) not in statusRouter or
host.name != node.name and ("/ndn/{}-site/{}".format(node.name, node.name)) not in statusPrefix ):
didNodeConverge = False
didNlsrConverge = False
host.cmd("echo " + str(didNodeConverge) + " > convergence-result &")
if didNlsrConverge:
print("NLSR has successfully converged.")
else:
print("NLSR has not converged. Exiting...")
self.net.stop()
sys.exit(1)
def startPings(self):
for host in self.net.hosts:
for other in self.net.hosts:
# Do not ping self
if host.name != other.name:
NDNPingClient.ping(host, other, self.options.nPings)
def failNode(self, host):
print("Bringing {} down".format(host.name))
host.nfd.stop()
def recoverNode(self, host):
print("Bringing {} up".format(host.name))
host.nfd.start()
host.nlsr.createFaces()
host.nlsr.start()
Nfdc.setStrategy(host, "/ndn/", self.options.strategy)
host.cmd("ndnpingserver /ndn/{}-site/{} > ping-server &".format(host.name, host.name))
def startPctPings(self):
nNodesToPing = int(round(len(self.net.hosts) * self.options.pctTraffic))
print "Each node will ping {} node(s)".format(nNodesToPing)
# Temporarily store all the nodes being pinged by a particular node
nodesPingedList = []
for host in self.net.hosts:
# Create a circular list
pool = cycle(self.net.hosts)
# Move iterator to current node
next(x for x in pool if host.name == x.name)
# Track number of nodes to ping scheduled for this node
nNodesScheduled = 0
while nNodesScheduled < nNodesToPing:
other = pool.next()
# Do not ping self
if host.name != other.name:
NDNPingClient.ping(host, other, self.options.nPings)
nodesPingedList.append(other)
# Always increment because in 100% case a node should not ping itself
nNodesScheduled = nNodesScheduled + 1
self.pingedDict[host] = nodesPingedList
nodesPingedList = []
@staticmethod
def register(name, experimentClass):
ExperimentManager.register(name, experimentClass)
View File
Whitespace-only changes.
@@ -1,73 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.nlsr import Nlsr, NlsrConfigGenerator
from mininet.log import info
import time, sys
class AdvertiseDelayedStartExperiment(Experiment):
'''Tests Name LSA data segmentation'''
def __init__(self, args):
Experiment.__init__(self, args)
def setup(self):
pass
def run(self):
pass
def startNlsr(self, checkConvergence = True):
# NLSR Security
if self.options.nlsrSecurity is True:
Nlsr.createKeysAndCertificates(self.net, self.options.workDir)
host1 = self.net.hosts[0]
host1.nlsr = Nlsr(host1, self.options)
host1.nlsr.start()
expectedTotalCount = 500
for i in range(0, expectedTotalCount):
host1.cmd("nlsrc advertise /long/name/to/exceed/max/packet/size/host1/{}".format(i))
time.sleep(60)
host2 = self.net.hosts[1]
host2.nlsr = Nlsr(host2, self.options)
host2.nlsr.start()
time.sleep(60)
advertiseCount = int(host2.cmd("nfdc fib | grep host1 | wc -l"))
info(advertiseCount)
if advertiseCount == expectedTotalCount:
info('\nSuccessfully advertised {} prefixes\n'.format(expectedTotalCount))
else:
info('\nAdvertising {} prefixes failed. Exiting...\n'.format(expectedTotalCount))
self.net.stop()
sys.exit(1)
Experiment.register("advertise-delayed-start", AdvertiseDelayedStartExperiment)
-66
View File
@@ -1,66 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.nlsr import Nlsr, NlsrConfigGenerator
from mininet.log import info
import time
class NlsrDelayedStartExperiment(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
def setup(self):
pass
def run(self):
pass
def startNlsr(self, checkConvergence = True):
# NLSR Security
if self.options.nlsrSecurity is True:
Nlsr.createKeysAndCertificates(self.net, self.options.workDir)
i = 1
# NLSR initialization
info('Starting NLSR on nodes\n')
for host in self.net.hosts:
host.nlsr = Nlsr(host, self.options)
host.nlsr.start()
# Wait 1/2 minute between starting NLSRs
# Wait 1 hour before starting last NLSR
if i == len(self.net.hosts) - 1:
info('Sleeping 1 hour before starting last NLSR')
time.sleep(3600)
else:
time.sleep(30)
i += 1
if checkConvergence:
self.checkConvergence()
Experiment.register("nlsr-delayed-start", NlsrDelayedStartExperiment)
@@ -1,65 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.ndn_ping_client import NDNPingClient
import time
class FailureExperiment(Experiment):
def __init__(self, args):
args["options"].nPings = 300
Experiment.__init__(self, args)
self.PING_COLLECTION_TIME_BEFORE_FAILURE = 60
self.PING_COLLECTION_TIME_AFTER_RECOVERY = 120
def run(self):
self.startPctPings()
# After the pings are scheduled, collect pings for 1 minute
time.sleep(self.PING_COLLECTION_TIME_BEFORE_FAILURE)
# Bring down CSU
for host in self.net.hosts:
if host.name == "csu":
self.failNode(host)
break
# CSU is down for 2 minutes
time.sleep(120)
# Bring CSU back up
for host in self.net.hosts:
if host.name == "csu":
self.recoverNode(host)
for other in self.net.hosts:
if host.name != other.name:
NDNPingClient.ping(host, other, self.PING_COLLECTION_TIME_AFTER_RECOVERY)
# Collect pings for more seconds after CSU is up
time.sleep(self.PING_COLLECTION_TIME_AFTER_RECOVERY)
Experiment.register("failure", FailureExperiment)
@@ -1,79 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.ndn_ping_client import NDNPingClient
import time
class MCNFailureExperiment(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
self.PING_COLLECTION_TIME_BEFORE_FAILURE = 60
self.PING_COLLECTION_TIME_AFTER_RECOVERY = 120
def getMostConnectedNode(self):
mcn = max(self.net.hosts, key=lambda host: len(host.intfNames()))
print "The most connected node is: {}".format(mcn.name)
return mcn
def setup(self):
if self.options.nPings != 0:
Experiment.setup(self)
def run(self):
mostConnectedNode = self.getMostConnectedNode()
if self.options.nPings != 0:
self.startPctPings()
# After the pings are scheduled, collect pings for 1 minute
time.sleep(self.PING_COLLECTION_TIME_BEFORE_FAILURE)
# Bring down MCN
self.failNode(mostConnectedNode)
# MCN is down for 2 minutes
time.sleep(int(self.options.arguments.waitTime))
# Bring MCN back up
self.recoverNode(mostConnectedNode)
# Restart pings
if self.options.nPings != 0:
for nodeToPing in self.pingedDict[mostConnectedNode]:
NDNPingClient.ping(mostConnectedNode, nodeToPing, self.PING_COLLECTION_TIME_AFTER_RECOVERY)
# Collect pings for more seconds after MCN is up
time.sleep(self.PING_COLLECTION_TIME_AFTER_RECOVERY)
else:
self.checkConvergence()
@staticmethod
def parseArguments(parser):
parser.add_argument("--wait-time", dest="waitTime", default="120",
help="[Experiment] Generic wait time for experiment use")
Experiment.register("mcn-failure", MCNFailureExperiment)
@@ -1,80 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.ndn_ping_client import NDNPingClient
import time
class MultipleFailureExperiment(Experiment):
def __init__(self, args):
self.PING_COLLECTION_TIME_BEFORE_FAILURE = 60
self.FAILURE_INTERVAL = 60
self.RECOVERY_INTERVAL = 60
# This is the number of pings required to make it through the full experiment
nInitialPings = (self.PING_COLLECTION_TIME_BEFORE_FAILURE +
len(args["net"].hosts) * (self.FAILURE_INTERVAL + self.RECOVERY_INTERVAL))
print("Scheduling with {} initial pings".format(nInitialPings))
Experiment.__init__(self, args)
self.options.nPings = nInitialPings
def run(self):
self.startPctPings()
# After the pings are scheduled, collect pings for 1 minute
time.sleep(self.PING_COLLECTION_TIME_BEFORE_FAILURE)
nNodesRemainingToFail = len(self.net.hosts)
# Fail and recover each node
for host in self.net.hosts:
# Fail the node
self.failNode(host)
# Stay in failure state for FAILURE_INTERVAL seconds
time.sleep(self.FAILURE_INTERVAL)
# Bring the node back up
start_time = time.time()
self.recoverNode(host)
recovery_time = int(time.time() - start_time)
# Number of pings required to reach the end of the test
nNodesRemainingToFail -= 1
nPings = ((self.RECOVERY_INTERVAL - recovery_time) +
nNodesRemainingToFail*(self.FAILURE_INTERVAL + self.RECOVERY_INTERVAL))
print("Scheduling with {} remaining pings".format(nPings))
# Restart pings
for nodeToPing in self.pingedDict[host]:
NDNPingClient.ping(host, nodeToPing, nPings)
time.sleep(self.RECOVERY_INTERVAL - recovery_time)
Experiment.register("multiple-failure", MultipleFailureExperiment)
@@ -1,66 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import sys
import time
from ndn.experiments.experiment import Experiment
class PrefixPropogationExperiment(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
def setup(self):
self.checkConvergence()
def run(self):
firstNode = self.net.hosts[0]
if self.options.nlsrSecurity:
firstNode.cmd("ndnsec-set-default /ndn/{}-site/%C1.Operator/op".format(firstNode.name))
print("Testing advertise")
firstNode.cmd("nlsrc advertise /testPrefix")
time.sleep(30)
for host in self.net.hosts:
if host.name != firstNode.name:
if (int(host.cmd("nfdc fib | grep testPrefix | wc -l")) != 1 or
int(host.cmd("nlsrc status | grep testPrefix | wc -l")) != 1):
print("Advertise test failed")
self.net.stop()
sys.exit(1)
print("Testing withdraw")
firstNode.cmd("nlsrc withdraw /testPrefix")
time.sleep(30)
for host in self.net.hosts:
if host.name != firstNode.name:
if (int(host.cmd("nfdc fib | grep testPrefix | wc -l")) != 0 or
int(host.cmd("nlsrc status | grep testPrefix | wc -l")) != 0):
print("Withdraw test failed")
self.net.stop()
sys.exit(1)
Experiment.register("prefix-propogation", PrefixPropogationExperiment)
View File
Whitespace-only changes.
-75
View File
@@ -1,75 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.nfdc import Nfdc
import time
import sys
class PSyncFull(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
self.syncPrefix = "/sync"
self.numUserPrefixesPerNode = 2
self.maxUpdatesPerUserPrefixPerNode = 3
def registerRouteToAllNeighbors(self, host):
for node in self.net.hosts:
for neighbor in node.connectionsTo(host):
ip = node.IP(neighbor[0])
Nfdc.createFace(host, ip)
Nfdc.registerRoute(host, self.syncPrefix, ip)
def start(self):
for host in self.net.hosts:
Nfdc.setStrategy(host, self.syncPrefix, "multicast")
self.registerRouteToAllNeighbors(host)
print("Starting psync-full-sync on all the nodes")
for host in self.net.hosts:
host.cmd("export NDN_LOG=examples.FullSyncApp=INFO")
host.cmd("psync-full-sync {} {} {} {} &> psync.logs &"
.format(self.syncPrefix, host.name, self.numUserPrefixesPerNode,
self.maxUpdatesPerUserPrefixPerNode))
print("Sleeping 5 minutes for convergence")
# Estimated time for 4 node default topology
time.sleep(300)
totalUpdates = int(host.cmd("grep -r Update {}/*/psync.logs | wc -l"
.format(self.options.workDir)))
expectedUpdates = (self.maxUpdatesPerUserPrefixPerNode *
len(self.net.hosts) * (len(self.net.hosts) - 1) *
self.numUserPrefixesPerNode)
if totalUpdates == expectedUpdates:
print("PSync full sync has successfully converged.")
else:
print("PSync full sync convergence was not successful. Exiting...")
self.net.stop()
sys.exit(1)
Experiment.register("psync-full", PSyncFull)
-59
View File
@@ -1,59 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.nfdc import Nfdc
import time
import sys
class PSyncPartial(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
def start(self):
host1 = self.net.hosts[0]
host1.cmd("export NDN_LOG=examples.PartialSyncProducerApp=INFO")
host1.cmd("psync-producer /sync /{} 10 1 &> producer.log &".format(host1.name))
time.sleep(1)
host1.cmd("export NDN_LOG=examples.PartialSyncConsumerApp=INFO:$NDN_LOG")
host1.cmd("psync-consumer /sync 5 &> consumer.log &")
print("Sleeping 90 seconds for convergence")
time.sleep(90)
consumerSubs = int(host1.cmd("cat consumer.log | grep -c Subscribing"))
consumerUpdates = int(host1.cmd("cat consumer.log | grep -c Update"))
producerPublish = int(host1.cmd("cat producer.log | grep -c Publish"))
if consumerSubs == 5 and consumerUpdates == 5 and producerPublish == 10:
print("PSync partial sync has successfully converged.")
else:
print("PSync partial sync convergence was not successful. Exiting...")
self.net.stop()
sys.exit(1)
Experiment.register("psync-partial", PSyncPartial)
@@ -1,73 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from ndn.experiments.experiment import Experiment
from ndn.apps.ndn_global_routing_helper import GlobalRoutingHelper
from mininet.log import info
class RoutingHelperExp(Experiment):
def __init__(self, args):
Experiment.__init__(self, args)
def start(self):
"""
Compute and add routes to NFD
"""
info('Adding static routes to NFD\n')
grh = GlobalRoutingHelper(self.net, self.options.faceType, self.options.routingType)
# For all host, pass self.net.hosts or a list, [self.net['a'], ..] or [self.net.hosts[0],.]
grh.addOrigin([self.net['a']], ["/abc"])
grh.calculateNPossibleRoutes()
'''
Experiment run with default topology, test cases won't work with other topologies
# With calculateNPossibleRoutes,
10 # routing = hr, N = All, from A, 3 routes needs to added to NFD.
A +++++++ B # A - B -- cost 10
+ + # A - C -- cost 10
10 + + 10 # A - D -- cost 20
+ + # Same goes for B being a source.
C D #
prefix "/abc" is advertise from node A, it should be reachable from all other nodes.
'''
if self.options.routingType == "link-state":
# This test only for link-state. Similar test can be done for hyperbolic routing.
routesFromA = self.net['a'].cmd("nfdc route | grep -v '/localhost/nfd'")
if '/ndn/b-site/b' not in routesFromA or \
'/ndn/c-site/c' not in routesFromA or \
'/ndn/d-site/d' not in routesFromA:
info("Route addition failed\n")
exit(-1)
routesToPrefix = self.net['b'].cmd("nfdc fib | grep '/abc'")
if '/abc' not in routesToPrefix:
info("Missing route to advertised prefix, Route addition failed\n")
exit(-1)
info('Route addition to NFD completed\n')
Experiment.register("centralize-routing", RoutingHelperExp)
-156
View File
@@ -1,156 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from Tkinter import *
LOG_LEVELS = [
"NONE",
"ERROR",
"WARN",
"INFO",
"DEBUG",
"TRACE",
"ALL"
]
class GuiFrame(Frame):
def __init__(self, notebook, prefValues, appId):
Frame.__init__(self, notebook)
self.prefValues = prefValues
self.appId = appId
self.row = 0
self.column = 0
def addEntryBox(self, label, variable, defaultValue=""):
variable.set(defaultValue)
Label(self, text=label).grid(row=self.row, sticky=E)
entry = Entry(self, textvariable=variable)
entry.grid(row=self.row, column=1)
self.row += 1
def addDropDown(self, label, variable, values, defaultValue=""):
variable.set(defaultValue)
Label(self, text=label).grid(row=self.row, sticky=E)
self.entry = apply(OptionMenu, (self, variable) + tuple(values))
self.entry.grid(row=self.row, column=1)
self.row += 1
def getPreferredOrDefaultValue(self, key, defaultValue):
if self.appId in self.prefValues:
return self.prefValues[self.appId][key]
else:
return defaultValue
class NfdFrame(GuiFrame):
def __init__(self, notebook, prefValues):
GuiFrame.__init__(self, notebook, prefValues, "nfd")
self.frameLabel = "NFD"
# log-level
self.logLevel = StringVar(self)
self.addDropDown("Log level:",
self.logLevel,
LOG_LEVELS,
self.getPreferredOrDefaultValue("log-level", LOG_LEVELS[3]))
def getValues(self):
return {
"log-level": self.logLevel.get()
}
class NlsrFrame(GuiFrame):
HYPERBOLIC_STATES = [
"off",
"on",
"dry-run"
]
def __init__(self, notebook, prefValues):
GuiFrame.__init__(self, notebook, prefValues, "nlsr")
self.frameLabel = "NLSR"
# general: network
self.network = StringVar(self)
self.addEntryBox("Network:",
self.network,
self.getPreferredOrDefaultValue("network", "/ndn"))
# general: site
self.site = StringVar(self)
self.addEntryBox("Site:", self.site, self.getPreferredOrDefaultValue("site", "/edu/site"))
# general: router
self.router = StringVar(self)
self.addEntryBox("Router:",
self.router,
self.getPreferredOrDefaultValue("router", "/%C1.Router/cs/host"))
# general: log-level
self.logLevel = StringVar(self)
self.addDropDown("Log level:",
self.logLevel,
LOG_LEVELS,
self.getPreferredOrDefaultValue("log-level", LOG_LEVELS[3]))
# hyperbolic: state
self.hyperbolicState = StringVar(self)
self.addDropDown("Hyperbolic routing:",
self.hyperbolicState,
self.HYPERBOLIC_STATES,
self.getPreferredOrDefaultValue("hyperbolic-state", self.HYPERBOLIC_STATES[0]))
# hyperbolic: angle
self.angle = StringVar(self)
self.addEntryBox("Angle:", self.angle, self.getPreferredOrDefaultValue("angle", "0.0"))
# hyperbolic: radius
self.radius = StringVar(self)
self.addEntryBox("Radius:", self.radius, self.getPreferredOrDefaultValue("radius", "0.0"))
# fib: max-faces-per-prefix
self.maxFaces = StringVar(self)
self.addEntryBox("Max faces per prefix:",
self.maxFaces,
self.getPreferredOrDefaultValue("max-faces-per-prefix", "0"))
def getValues(self):
return {
"network": self.network.get(),
"site": self.site.get(),
"router": self.router.get(),
"log-level": self.logLevel.get(),
"hyperbolic-state": self.hyperbolicState.get(),
"angle": self.angle.get(),
"radius": self.radius.get(),
"max-faces-per-prefix": self.maxFaces.get()
}
-158
View File
@@ -1,158 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
#
# This file incorporates work covered by the following copyright and
# permission notice:
#
# Mininet 2.3.0d1 License
#
# Copyright (c) 2013-2016 Open Networking Laboratory
# Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
# The Leland Stanford Junior University
#
# Original authors: Bob Lantz and Brandon Heller
#
# We are making Mininet available for public use and benefit with the
# expectation that others will use, modify and enhance the Software and
# contribute those enhancements back to the community. However, since we
# would like to make the Software available for broadest use, with as few
# restrictions as possible permission is hereby granted, free of charge, to
# any person obtaining a copy of this Software to deal in the Software
# under the copyrights without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# The name and trademarks of copyright holder(s) may NOT be used in
# advertising or publicity pertaining to the Software or any derivatives
# without specific, written prior permission.
from mininet.node import CPULimitedHost, Host, Node
from mininet.examples.cluster import RemoteMixin
from ndn.nfd import Nfd
class NdnHostCommon():
"Common methods of NdnHost and CpuLimitedNdnHost"
def configNdn(self):
self.buildPeerIp()
def buildPeerIp(self):
for iface in self.intfList():
link = iface.link
if link:
node1, node2 = link.intf1.node, link.intf2.node
if node1 == self:
self.peerList[node2.name] = link.intf2.node.IP(link.intf2)
else:
self.peerList[node1.name] = link.intf1.node.IP(link.intf1)
inited = False
@classmethod
def init(cls):
"Initialization for NDNHost class"
cls.inited = True
class NdnHost(Host, NdnHostCommon):
"NDNHost is a Host that always runs NFD"
def __init__(self, name, **kwargs):
Host.__init__(self, name, **kwargs)
if not NdnHost.inited:
NdnHostCommon.init()
# Create home directory for a node
self.homeFolder = "%s/%s" % (self.params['workdir'], self.name)
self.cmd("mkdir -p %s" % self.homeFolder)
self.cmd("cd %s" % self.homeFolder)
self.nfd = None
self.peerList = {}
def config(self, app=None, cache=None, **params):
r = Node.config(self, **params)
self.setParam(r, 'app', app=app)
self.setParam(r, 'cache', cache=cache)
return r
def terminate(self):
"Stop node."
if self.nfd is not None:
self.nfd.stop()
Host.terminate(self)
class CpuLimitedNdnHost(CPULimitedHost, NdnHostCommon):
'''CPULimitedNDNHost is a Host that always runs NFD and extends CPULimitedHost.
It should be used when one wants to limit the resources of NDN routers and hosts '''
def __init__(self, name, sched='cfs', **kwargs):
CPULimitedHost.__init__(self, name, sched, **kwargs)
if not NdnHost.inited:
NdnHostCommon.init()
# Create home directory for a node
self.homeFolder = "%s/%s" % (self.params['workdir'], self.name)
self.cmd("mkdir -p %s" % self.homeFolder)
self.cmd("cd %s" % self.homeFolder)
self.nfd = None
self.peerList = {}
def config(self, app=None, cpu=None, cores=None, cache=None, **params):
r = CPULimitedHost.config(self,cpu,cores, **params)
self.setParam(r, 'app', app=app)
self.setParam(r, 'cache', cache=cache)
return r
def terminate(self):
"Stop node."
if self.nfd is not None:
self.nfd.stop()
CPULimitedHost.terminate(self)
class RemoteNdnHost(RemoteMixin, NdnHost):
"A node on a remote server"
pass
-71
View File
@@ -1,71 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time, sys, os
from ndn.ndn_application import NdnApplication
from ndn.util import copyExistentFile
class Nfd(NdnApplication):
def __init__(self, node, csSize):
NdnApplication.__init__(self, node)
self.logLevel = node.params["params"].get("nfd-log-level", "INFO")
self.confFile = "{}/nfd.conf".format(node.homeFolder)
self.logFile = "{}/nfd.log".format(node.homeFolder)
self.sockFile = "/var/run/{}.sock".format(node.name)
self.ndnFolder = "{}/.ndn".format(node.homeFolder)
self.clientConf = "{}/client.conf".format(self.ndnFolder)
# Copy nfd.conf file from /usr/local/etc/ndn or /etc/ndn to the node's home directory
# Use nfd.conf as default configuration for NFD, else use the sample
possibleConfPaths = ["/usr/local/etc/ndn/nfd.conf.sample", "/usr/local/etc/ndn/nfd.conf",
"/etc/ndn/nfd.conf.sample", "/etc/ndn/nfd.conf"]
copyExistentFile(node, possibleConfPaths, self.confFile)
# Set log level
node.cmd("infoedit -f {} -s log.default_level -v {}".format(self.confFile, self.logLevel))
# Open the conf file and change socket file name
node.cmd("infoedit -f {} -s face_system.unix.path -v /var/run/{}.sock".format(self.confFile, node.name))
# Set CS size
node.cmd("infoedit -f {} -s tables.cs_max_packets -v {}".format(self.confFile, csSize))
# Make NDN folder
node.cmd("sudo mkdir {}".format(self.ndnFolder))
# Copy client configuration to host
possibleClientConfPaths = ["/usr/local/etc/ndn/client.conf.sample", "/etc/ndn/client.conf.sample"]
copyExistentFile(node, possibleClientConfPaths, self.clientConf)
# Change the unix socket
node.cmd("sudo sed -i 's|nfd.sock|{}.sock|g' {}".format(node.name, self.clientConf))
# Change home folder
node.cmd("export HOME={}".format(node.homeFolder))
node.cmd("ndnsec-keygen /localhost/operator | ndnsec-install-cert -")
def start(self):
NdnApplication.start(self, "setsid nfd --config {} > {} 2>&1 &".format(self.confFile, self.logFile))
time.sleep(2)
-87
View File
@@ -1,87 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
#
# This file incorporates work covered by the following copyright and
# permission notice:
#
# Mininet 2.3.0d1 License
#
# Copyright (c) 2013-2016 Open Networking Laboratory
# Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
# The Leland Stanford Junior University
#
# Original authors: Bob Lantz and Brandon Heller
#
# We are making Mininet available for public use and benefit with the
# expectation that others will use, modify and enhance the Software and
# contribute those enhancements back to the community. However, since we
# would like to make the Software available for broadest use, with as few
# restrictions as possible permission is hereby granted, free of charge, to
# any person obtaining a copy of this Software to deal in the Software
# under the copyrights without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# The name and trademarks of copyright holder(s) may NOT be used in
# advertising or publicity pertaining to the Software or any derivatives
# without specific, written prior permission.
from mininet.examples.cluster import Placer
nodePlace = []
class PopulatePlacement():
def __init__( self, placeList ):
global nodePlace
nodePlace = placeList
class GuidedPlacer( Placer ):
"Guided placement"
def __init__( self, *args, **kwargs ):
Placer.__init__( self, *args, **kwargs )
self.count = 0
def place( self, nodename ):
assert nodename #please pylint
while(True):
global nodePlace
if nodePlace[self.count] != 0:
nodePlace[self.count] -= 1
# args[self.count] is not zero, hence return the server at that position
# so that if args[0] is 7 and servers[0] is Europa then place 7 nodes on Europa
return self.servers[self.count]
else:
# while makes sure we go back to the if after this
self.count += 1
-90
View File
@@ -1,90 +0,0 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2018, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN 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.
#
# Mini-NDN 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 Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
#
# This file incorporates work covered by the following copyright and
# permission notice:
#
# Mininet 2.3.0d1 License
#
# Copyright (c) 2013-2016 Open Networking Laboratory
# Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
# The Leland Stanford Junior University
#
# Original authors: Bob Lantz and Brandon Heller
#
# We are making Mininet available for public use and benefit with the
# expectation that others will use, modify and enhance the Software and
# contribute those enhancements back to the community. However, since we
# would like to make the Software available for broadest use, with as few
# restrictions as possible permission is hereby granted, free of charge, to
# any person obtaining a copy of this Software to deal in the Software
# under the copyrights without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# The name and trademarks of copyright holder(s) may NOT be used in
# advertising or publicity pertaining to the Software or any derivatives
# without specific, written prior permission.
from mininet.link import TCLink
from mininet.examples.cluster import RemoteLink, RemoteGRELink
class RemoteNdnLink( TCLink, RemoteLink ):
"A RemoteLink is a link between nodes which may be on different servers"
def __init__( self, node1, node2, **kwargs ):
"""Initialize a RemoteLink
see Link() for parameters"""
# Create links on remote node
self.node1 = node1
self.node2 = node2
self.tunnel = None
kwargs.setdefault( 'params1', {} )
kwargs.setdefault( 'params2', {} )
self.cmd = None # satisfy pylint
TCLink.__init__( self, node1, node2, **kwargs )
class RemoteGRENdnLink( TCLink, RemoteGRELink ):
def __init__(self, node1, node2, **kwargs):
"""Initialize a RemoteLink
see Link() for parameters"""
# Create links on remote node
self.node1 = node1
self.node2 = node2
self.tunnel = None
kwargs.setdefault( 'params1', {} )
kwargs.setdefault( 'params2', {} )
self.cmd = None # satisfy pylint
TCLink.__init__( self, node1, node2, **kwargs )
@@ -0,0 +1,602 @@
diff --git a/ndn-cxx/security/v2/key-chain.cpp b/ndn-cxx/security/v2/key-chain.cpp
index 8043635..b9af6f0 100644
--- a/ndn-cxx/security/v2/key-chain.cpp
+++ b/ndn-cxx/security/v2/key-chain.cpp
@@ -25,6 +25,7 @@
#include "ndn-cxx/util/config-file.hpp"
#include "ndn-cxx/util/logger.hpp"
#include "ndn-cxx/util/sha256.hpp"
+#include "ndn-cxx/util/dummy-keychain.hpp"
#include "ndn-cxx/security/pib/pib-memory.hpp"
#include "ndn-cxx/security/pib/pib-sqlite3.hpp"
@@ -163,7 +164,7 @@ KeyChain::getDefaultKeyParams()
//
KeyChain::KeyChain()
- : KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
+ : KeyChain("pib-dummy", "tpm-dummy", true)
{
}
diff --git a/ndn-cxx/util/dummy-keychain.cpp b/ndn-cxx/util/dummy-keychain.cpp
new file mode 100644
index 0000000..aa24465
--- /dev/null
+++ b/ndn-cxx/util/dummy-keychain.cpp
@@ -0,0 +1,346 @@
+/* -*- 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/>.
+ **/
+
+#include "dummy-keychain.hpp"
+
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/security/transform/public-key.hpp>
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/stream.hpp>
+
+namespace ndn {
+namespace security {
+
+static const uint8_t DUMMY_CERT[] =
+ "Bv0CqQclCAVkdW1teQgDS0VZCAgtnChyuKo7YAgCTkEICf0AAAFe3zzGfBQJGAEC"
+ "GQQANu6AFf0BJjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOJSa1j6"
+ "JAzobrmtlUdJi38EWQZOigLykf9psImvIu7pa29Q3apBXENcV1E9687FmfY85Ec3"
+ "/onMtN7WG/wiuKiu/9eOr5WslD3VGDgxhesx80ygP0GNsN8FzsMl0lRKduXx3wG4"
+ "MCT8CX7uA4n4JbHY+0QaKUEEMRCiXcRAtF+yKfr+GaVeSemg+i/LR+6CSgpOyH0K"
+ "ogH9nlNhBn1Hxyc8X+B/nEu6P6NNEKkSnhT1jAbWtT1eL3BPGK/HNY19w9k2Ln6/"
+ "OYlhaHfB4m0oR/ePcUguQBwTgYS+40YQYUPivBsSQv3X2/7+gGLhIzA4YppwOooK"
+ "RGhbmL8zF2evmJ8CAwEAARZHGwEBHBgHFggFZHVtbXkIA0tFWQgILZwocriqO2D9"
+ "AP0m/QD+DzIwMTcxMDAyVDIyMzczNv0A/w8yMDE4MTAwMlQyMjM3MzUX/QEAMBUV"
+ "O51BEQwxp646i7IuHkuc1C/LISnOP2+wBFF2Ea1ht9MKjKkyJdmB1/GAOiR3njKd"
+ "UgRjBlownL11EwYDxkPY39RR05TmhF6PkpP81Ro/Vzv7rtSi/dxFIZXCiyuKPRUx"
+ "E0pZelPWVs3zMfqQ+8rWG89Kqs1vM0dglLBzlX9Lbim71TyLmaJaMmmBKv8+eQ22"
+ "CN71sRZOovl1kKcTHpOm61nD3C1n9GRflFtaMAXE/XU4zMJVzBv6XwQl6PCIc9H2"
+ "vjLa28ruVjhMGxqCGhziTC2eR56SUixrnEcbOKT0R+8+0AFnZIjdYglOZPcVwTVB"
+ "G6OxECJOuSoREcd1Ww==;";
+
+static const uint8_t DUMMY_SIGNATURE[] =
+ {0x17, 0xfd, 0x01, 0x00, 0x93, 0x15, 0x09, 0x49, 0x79, 0x9e, 0xb7, 0x9c, 0xd3, 0xc1, 0xbf, 0x61,
+ 0x89, 0xd5, 0xd9, 0xca, 0xf2, 0xb0, 0x14, 0xae, 0x72, 0x7c, 0x1f, 0x8f, 0xf5, 0xb1, 0x70, 0xd6,
+ 0x9b, 0x8f, 0xf8, 0xd7, 0x2d, 0xbc, 0x92, 0x6f, 0x7d, 0x77, 0x96, 0x46, 0xea, 0xd4, 0x7d, 0x90,
+ 0xbc, 0x7a, 0xeb, 0xe2, 0x03, 0x93, 0xb1, 0xd2, 0x62, 0xec, 0x9d, 0xff, 0x9c, 0x9c, 0x2a, 0x14,
+ 0x7d, 0x23, 0xca, 0x29, 0x3d, 0x15, 0x1a, 0x40, 0x42, 0x2c, 0x59, 0x33, 0x8a, 0xf7, 0xc0, 0x6b,
+ 0xc4, 0x9c, 0xf3, 0xc4, 0x99, 0xa4, 0x1a, 0x60, 0xf5, 0x28, 0x7d, 0x4c, 0xef, 0x43, 0x7d, 0xbd,
+ 0x7d, 0x00, 0x51, 0xee, 0x41, 0xf5, 0x25, 0x80, 0xce, 0xe6, 0x64, 0x4f, 0x75, 0x54, 0xf3, 0xb2,
+ 0x99, 0x9a, 0x0f, 0x93, 0x9a, 0x28, 0x1d, 0xfe, 0x12, 0x8a, 0xe0, 0xc1, 0x02, 0xeb, 0xa4, 0x35,
+ 0x52, 0x88, 0xac, 0x44, 0x1a, 0x44, 0x82, 0x97, 0x4f, 0x5f, 0xa8, 0xd8, 0x9f, 0x67, 0x38, 0xa8,
+ 0x64, 0xb6, 0x62, 0x99, 0xbd, 0x96, 0x3c, 0xf5, 0x86, 0x09, 0x5c, 0x97, 0x6b, 0x8f, 0xae, 0xe0,
+ 0x60, 0xe7, 0x23, 0x98, 0x6a, 0xee, 0xc1, 0xb0, 0x14, 0xbe, 0x46, 0x2c, 0xfb, 0xa7, 0x27, 0x73,
+ 0xe4, 0xf3, 0x26, 0x33, 0xba, 0x99, 0xd4, 0x01, 0x38, 0xa8, 0xf2, 0x9e, 0x87, 0xe0, 0x71, 0x0b,
+ 0x25, 0x44, 0x07, 0x35, 0x88, 0xab, 0x67, 0x27, 0x56, 0x0e, 0xb5, 0xb5, 0xe8, 0x27, 0xb4, 0x49,
+ 0xdc, 0xb8, 0x48, 0x31, 0xff, 0x99, 0x48, 0xab, 0x11, 0xb4, 0xa0, 0xdf, 0x8a, 0x6d, 0xff, 0x43,
+ 0x69, 0x32, 0xa7, 0xbc, 0x63, 0x9d, 0x0f, 0xe0, 0x95, 0x34, 0x36, 0x25, 0x4b, 0x3e, 0x36, 0xbd,
+ 0x81, 0x91, 0x0b, 0x91, 0x9f, 0x3a, 0x04, 0xa2, 0x44, 0x28, 0x19, 0xa1, 0x38, 0x21, 0x4f, 0x25,
+ 0x59, 0x8a, 0x48, 0xc2};
+
+const std::string DummyPib::SCHEME = "pib-dummy";
+const std::string DummyTpm::SCHEME = "tpm-dummy";
+
+NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(DummyPib);
+NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(DummyTpm);
+
+DummyPib::DummyPib(const std::string& locator)
+{
+}
+
+void
+DummyPib::setTpmLocator(const std::string& tpmLocator)
+{
+ m_tpmLocator = tpmLocator;
+}
+
+std::string
+DummyPib::getTpmLocator() const
+{
+ return m_tpmLocator;
+}
+
+bool
+DummyPib::hasIdentity(const Name& identityName) const
+{
+ return true;
+}
+
+void
+DummyPib::addIdentity(const Name& identityName)
+{
+}
+
+void
+DummyPib::removeIdentity(const Name& identity)
+{
+}
+
+void
+DummyPib::clearIdentities()
+{
+}
+
+std::set<Name>
+DummyPib::getIdentities() const
+{
+ std::set<Name> identities;
+ identities.insert("/dummy");
+ return identities;
+}
+
+void
+DummyPib::setDefaultIdentity(const Name& identityName)
+{
+}
+
+Name
+DummyPib::getDefaultIdentity() const
+{
+ return "/dummy";
+}
+
+bool
+DummyPib::hasKey(const Name& keyName) const
+{
+ return true;
+}
+
+void
+DummyPib::addKey(const Name& identity, const Name& keyName,
+ const uint8_t* key, size_t keyLen)
+{
+}
+
+void
+DummyPib::removeKey(const Name& keyName)
+{
+}
+
+Buffer
+DummyPib::getKeyBits(const Name& keyName) const
+{
+ typedef boost::iostreams::stream<boost::iostreams::array_source> arrayStream;
+ arrayStream
+ is(reinterpret_cast<const char*>(DUMMY_CERT), sizeof(DUMMY_CERT));
+ auto cert = io::load<v2::Certificate>(is, io::BASE64);
+ return cert->getPublicKey();
+}
+
+std::set<Name>
+DummyPib::getKeysOfIdentity(const Name& identity) const
+{
+ std::set<Name> keys;
+ keys.insert("/dummy/KEY/-%9C%28r%B8%AA%3B%60");
+ return keys;
+}
+
+void
+DummyPib::setDefaultKeyOfIdentity(const Name& identity, const Name& keyName)
+{
+}
+
+Name
+DummyPib::getDefaultKeyOfIdentity(const Name& identity) const
+{
+ return "/dummy/KEY/-%9C%28r%B8%AA%3B%60";
+}
+
+bool
+DummyPib::hasCertificate(const Name& certName) const
+{
+ return true;
+}
+
+void
+DummyPib::addCertificate(const v2::Certificate& certificate)
+{
+}
+
+void
+DummyPib::removeCertificate(const Name& certName)
+{
+}
+
+v2::Certificate
+DummyPib::getCertificate(const Name& certificateName) const
+{
+ static shared_ptr<v2::Certificate> cert = nullptr;
+ if (cert == nullptr) {
+ typedef boost::iostreams::stream<boost::iostreams::array_source> arrayStream;
+ arrayStream
+ is(reinterpret_cast<const char*>(DUMMY_CERT), sizeof(DUMMY_CERT));
+ cert = io::load<v2::Certificate>(is, io::BASE64);
+ }
+
+ return *cert;
+}
+
+std::set<Name>
+DummyPib::getCertificatesOfKey(const Name& keyName) const
+{
+ std::set<Name> certs;
+ certs.insert("/dummy/KEY/-%9C%28r%B8%AA%3B%60/self/%FD%00%00%01%5E%DF%3Bv%01");
+ return certs;
+}
+
+void
+DummyPib::setDefaultCertificateOfKey(const Name& keyName, const Name& certName)
+{
+}
+
+v2::Certificate
+DummyPib::getDefaultCertificateOfKey(const Name& keyName) const
+{
+ static shared_ptr<v2::Certificate> cert = nullptr;
+ if (cert == nullptr) {
+ typedef boost::iostreams::stream<boost::iostreams::array_source> arrayStream;
+ arrayStream
+ is(reinterpret_cast<const char*>(DUMMY_CERT), sizeof(DUMMY_CERT));
+ cert = io::load<v2::Certificate>(is, io::BASE64);
+ }
+
+ return *cert;
+}
+
+std::string
+DummyPib::getScheme()
+{
+ return DummyPib::SCHEME;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+
+namespace tpm {
+
+DummyKeyHandle::DummyKeyHandle(shared_ptr<transform::PrivateKey> key)
+{
+}
+
+ConstBufferPtr
+DummyKeyHandle::doSign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const
+{
+ return make_shared<Buffer>(DUMMY_SIGNATURE, sizeof(DUMMY_SIGNATURE));
+}
+
+bool
+DummyKeyHandle::doVerify(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t bufLen,
+ const uint8_t* sig, size_t sigLen) const
+{
+ return true;
+}
+
+ConstBufferPtr
+DummyKeyHandle::doDecrypt(const uint8_t* cipherText, size_t cipherTextLen) const
+{
+ throw Error("Not supported");
+}
+
+ConstBufferPtr
+DummyKeyHandle::doDerivePublicKey() const
+{
+ throw Error("Not supported");
+}
+
+} // namespace tpm
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+
+DummyTpm::DummyTpm(const std::string& locator)
+{
+}
+
+bool
+DummyTpm::isTerminalMode() const
+{
+ return false;
+}
+
+void
+DummyTpm::setTerminalMode(bool isTerminal) const
+{
+}
+
+bool
+DummyTpm::isTpmLocked() const
+{
+ return false;
+}
+
+bool
+DummyTpm::doHasKey(const Name& keyName) const
+{
+ return false;
+}
+
+unique_ptr<tpm::KeyHandle>
+DummyTpm::doGetKeyHandle(const Name& keyName) const
+{
+ unique_ptr<tpm::KeyHandle> m_dummyKeyHandle = make_unique<tpm::DummyKeyHandle>(nullptr);
+ return m_dummyKeyHandle;
+}
+
+unique_ptr<tpm::KeyHandle>
+DummyTpm::doCreateKey(const Name& identity, const KeyParams& params)
+{
+ unique_ptr<tpm::KeyHandle> m_dummyKeyHandle = make_unique<tpm::DummyKeyHandle>(nullptr);
+ return m_dummyKeyHandle;
+}
+
+void
+DummyTpm::doDeleteKey(const Name& keyName)
+{
+ throw Error("Not supported");
+}
+
+ConstBufferPtr
+DummyTpm::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
+{
+ throw Error("Not supported");
+}
+
+void
+DummyTpm::doImportKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen)
+{
+ throw Error("Not supported");
+}
+
+std::string
+DummyTpm::getScheme()
+{
+ return DummyTpm::SCHEME;
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/ndn-cxx/util/dummy-keychain.hpp b/ndn-cxx/util/dummy-keychain.hpp
new file mode 100644
index 0000000..d1432a6
--- /dev/null
+++ b/ndn-cxx/util/dummy-keychain.hpp
@@ -0,0 +1,223 @@
+/* -*- 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/>.
+ **/
+
+#ifndef NDNSIM_UTILS_DUMMY_KEYCHAIN_HPP
+#define NDNSIM_UTILS_DUMMY_KEYCHAIN_HPP
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/security/security-common.hpp>
+#include <ndn-cxx/security/pib/pib-impl.hpp>
+#include <ndn-cxx/security/tpm/back-end.hpp>
+#include <ndn-cxx/security/transform/private-key.hpp>
+
+namespace ndn {
+namespace security {
+
+using pib::PibImpl;
+using tpm::BackEnd;
+using tpm::KeyHandle;
+
+class DummyPib : public PibImpl
+{
+public:
+ class Error : public PibImpl::Error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : PibImpl::Error(what)
+ {
+ }
+ };
+
+public:
+ explicit DummyPib(const std::string& locator);
+
+ // TPM management
+ void
+ setTpmLocator(const std::string& tpmLocator) override;
+
+ std::string
+ getTpmLocator() const override;
+
+ // Identity manangement
+ bool
+ hasIdentity(const Name& identityName) const override;
+
+ void
+ addIdentity(const Name& identityName) override;
+
+ void
+ removeIdentity(const Name& identity) override;
+
+ void
+ clearIdentities() override;
+
+ std::set<Name>
+ getIdentities() const override;
+
+ void
+ setDefaultIdentity(const Name& identityName) override;
+
+ Name
+ getDefaultIdentity() const override;
+
+ // Key management
+ bool
+ hasKey(const Name& keyName) const override;
+
+ void
+ addKey(const Name& identity, const Name& keyName, const uint8_t* key,
+ size_t keyLen) override;
+
+ void
+ removeKey(const Name& keyName) override;
+
+ Buffer
+ getKeyBits(const Name& keyName) const override;
+
+ std::set<Name>
+ getKeysOfIdentity(const Name& identity) const override;
+
+ void
+ setDefaultKeyOfIdentity(const Name& identity, const Name& keyName) override;
+
+ Name
+ getDefaultKeyOfIdentity(const Name& identity) const override;
+
+ // certificate management
+ bool
+ hasCertificate(const Name& certName) const override;
+
+ void
+ addCertificate(const v2::Certificate& certificate) override;
+
+ void
+ removeCertificate(const Name& certName) override;
+
+ v2::Certificate
+ getCertificate(const Name& certificateName) const override;
+
+ std::set<Name>
+ getCertificatesOfKey(const Name& keyName) const override;
+
+ void
+ setDefaultCertificateOfKey(const Name& keyName, const Name& certName) override;
+
+ v2::Certificate
+ getDefaultCertificateOfKey(const Name& keyName) const override;
+
+ static std::string
+ getScheme();
+
+ static const std::string SCHEME;
+
+private:
+ std::string m_tpmLocator;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+
+namespace tpm {
+
+class DummyKeyHandle : public KeyHandle
+{
+public:
+ explicit
+ DummyKeyHandle(shared_ptr<transform::PrivateKey> key);
+
+private:
+ ConstBufferPtr
+ doSign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const final;
+
+ bool
+ doVerify(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t bufLen,
+ const uint8_t* sig, size_t sigLen) const final;
+
+ ConstBufferPtr
+ doDecrypt(const uint8_t* cipherText, size_t cipherTextLen) const final;
+
+ ConstBufferPtr
+ doDerivePublicKey() const final;
+};
+
+} // namespace tpm
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+
+class DummyTpm : public BackEnd
+{
+public:
+ class Error : public BackEnd::Error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : BackEnd::Error(what)
+ {
+ }
+ };
+
+public:
+ explicit DummyTpm(const std::string& locator);
+
+ bool
+ isTerminalMode() const override;
+
+ void
+ setTerminalMode(bool isTerminal) const override;
+
+ bool
+ isTpmLocked() const override;
+
+ ConstBufferPtr
+ sign(const uint8_t* buf, size_t size, const Name& keyName, DigestAlgorithm digestAlgorithm) const;
+
+ static std::string
+ getScheme();
+
+private:
+ bool
+ doHasKey(const Name& keyName) const final;
+
+ unique_ptr<tpm::KeyHandle>
+ doGetKeyHandle(const Name& keyName) const final;
+
+ unique_ptr<tpm::KeyHandle>
+ doCreateKey(const Name& identity, const KeyParams& params) final;
+
+ void
+ doDeleteKey(const Name& keyName) final;
+
+ ConstBufferPtr
+ doExportKey(const Name& keyName, const char* pw, size_t pwLen) final;
+
+ void
+ doImportKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen) final;
+
+public:
+ static const std::string SCHEME;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDNSIM_UTILS_DUMMY_KEYCHAIN_HPP
+2 -1
View File
@@ -1 +1,2 @@
python-igraph
python-igraph
setuptools
+5 -2
View File
@@ -1,10 +1,13 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
from minindn import __version__
setup(
name = "Mini-NDN",
version = '0.4.0',
version = __version__,
description='Mininet based NDN emulator',
packages = find_packages(),
scripts = ['bin/minindn', 'bin/minindnedit'],
)
print(find_packages())