**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
No files matched your search
@@ -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
|
||||
@@ -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.
|
||||
@@ -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`.
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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`
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
## 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
|
||||
|
||||

|
||||
|
||||
* **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
|
||||

|
||||
|
||||
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
|
||||

|
||||
|
||||
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
|
||||

|
||||
|
||||
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
|
||||

|
||||
|
||||
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*
|
||||
|
||||

|
||||
|
||||
#### 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.
|
||||
|
||||

|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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']
|
||||
@@ -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.
|
||||
@@ -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 |
|
||||
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
|
||||
@@ -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>`_.
|
||||
|
||||
@@ -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.
|
||||
|
Before Width: | Height: | Size: 865 B |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 971 B |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 876 B |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
@@ -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>`_
|
||||
@@ -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.
|
||||
@@ -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>
|
||||
@@ -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 |
@@ -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
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
__version__ = '0.5.0'
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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))
|
||||
@@ -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:
|
||||
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])
|
||||
|
||||
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):
|
||||
def addOrigin(self, nodes, prefix):
|
||||
"""
|
||||
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
|
||||
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
|
||||
"""
|
||||
r1 = [key for key in sourceNode][0]
|
||||
r2 = [key for key in destNode][0]
|
||||
for node in nodes:
|
||||
self.namePrefixes[node.name] = prefix
|
||||
|
||||
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 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.
|
||||
|
||||
debug("Distance from {} to {} is {}".format(sourceNode, destNode, hyperbolicDistance))
|
||||
return hyperbolicDistance
|
||||
: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
|
||||
self.calculateNPossibleRoutes(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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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))
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1 +1,2 @@
|
||||
python-igraph
|
||||
setuptools
|
||||
@@ -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())
|
||||