blob: 8a2f49c8dbb954ad5e250dea87a7ee3b5d13057e [file] [log] [blame]
Vince Lehmanb8b18062015-07-14 13:07:22 -05001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
Alexander Lane9944cf52018-05-17 12:16:50 -05003# Copyright (C) 2015-2018, The University of Memphis,
Ashlesh Gawandeda475f02017-03-01 17:20:58 -06004# Arizona Board of Regents,
5# Regents of the University of California.
Vince Lehmanb8b18062015-07-14 13:07:22 -05006#
7# This file is part of Mini-NDN.
8# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
9#
10# Mini-NDN is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# Mini-NDN is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with Mini-NDN, e.g., in COPYING.md file.
22# If not, see <http://www.gnu.org/licenses/>.
ashu34c3ee02015-03-25 14:41:14 -050023
24import time
25import sys
Ashlesh Gawanded9c9e522015-10-15 16:40:12 -050026from itertools import cycle
ashu34c3ee02015-03-25 14:41:14 -050027
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050028from mininet.log import info
29
Vince Lehman3b8bc652015-06-18 15:01:47 -050030from ndn import ExperimentManager
Alexander Lane6f7a64f2018-05-17 15:01:14 -050031from ndn.apps.nfdc import Nfdc
Vince Lehman3b8bc652015-06-18 15:01:47 -050032
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050033from ndn.apps.nlsr import Nlsr, NlsrConfigGenerator
34from ndn.apps.ndn_ping_client import NDNPingClient
35
ashu34c3ee02015-03-25 14:41:14 -050036class Experiment:
37
Vince Lehman3b8bc652015-06-18 15:01:47 -050038 def __init__(self, args):
39 self.net = args["net"]
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050040 self.options = args["options"]
Ashlesh Gawanded9c9e522015-10-15 16:40:12 -050041
42 # Used to restart pings on the recovered node if any
43 self.pingedDict = {}
44
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050045 def afterNfdStart(self):
46 pass
47
ashu34c3ee02015-03-25 14:41:14 -050048 def start(self):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050049 self.afterNfdStart()
50 if self.options.isNlsrEnabled is True:
51 self.startNlsr()
ashu34c3ee02015-03-25 14:41:14 -050052 self.setup()
53 self.run()
54
55 def setup(self):
56 for host in self.net.hosts:
57 # Set strategy
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050058 Nfdc.setStrategy(host, "/ndn/", self.options.strategy)
ashu34c3ee02015-03-25 14:41:14 -050059
60 # Start ping server
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050061 host.cmd("ndnpingserver /ndn/{}-site/{} > ping-server &".format(host.name, host.name))
ashu34c3ee02015-03-25 14:41:14 -050062
63 # Create folder to store ping data
64 host.cmd("mkdir ping-data")
65
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050066 def startNlsr(self, checkConvergence = True):
67 # NLSR Security
68 if self.options.nlsrSecurity is True:
69 Nlsr.createKeysAndCertificates(self.net, self.options.workDir)
70
71 # NLSR initialization
72 info('Starting NLSR on nodes\n')
73 for host in self.net.hosts:
74 host.nlsr = Nlsr(host, self.options)
75 host.nlsr.start()
76
77 for host in self.net.hosts:
78 nlsrStatus = host.cmd("ps -g | grep 'nlsr -f {}/[n]lsr.conf'".format(host.homeFolder))
79 if not host.nlsr.isRunning or not nlsrStatus:
80 print("NLSR on host {} is not running. Printing log file and exiting...".format(host.name))
81 print(host.cmd("tail {}/log/nlsr.log".format(host.homeFolder)))
82 self.net.stop()
83 sys.exit(1)
84
85 if checkConvergence:
86 self.checkConvergence()
Ashlesh Gawande5f470202017-02-25 12:02:53 -060087
88 def checkConvergence(self, convergenceTime = None):
89 if convergenceTime is None:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050090 convergenceTime = self.options.ctime
Ashlesh Gawande5f470202017-02-25 12:02:53 -060091
ashu34c3ee02015-03-25 14:41:14 -050092 # Wait for convergence time period
Ashlesh Gawande5f470202017-02-25 12:02:53 -060093 print "Waiting " + str(convergenceTime) + " seconds for convergence..."
94 time.sleep(convergenceTime)
ashu34c3ee02015-03-25 14:41:14 -050095 print "...done"
96
97 # To check whether all the nodes of NLSR have converged
98 didNlsrConverge = True
99
100 # Checking for convergence
101 for host in self.net.hosts:
Ashlesh Gawandef932a182016-12-19 23:45:26 -0600102 statusRouter = host.cmd("nfdc fib list | grep site/%C1.Router/cs/")
103 statusPrefix = host.cmd("nfdc fib list | grep ndn | grep site | grep -v Router")
ashu34c3ee02015-03-25 14:41:14 -0500104 didNodeConverge = True
Ashlesh Gawandef6a610b2017-02-21 14:48:08 -0600105 for node in self.net.hosts:
106 # Node has its own router name in the fib list, but not name prefix
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500107 if ( ("/ndn/{}-site/%C1.Router/cs/{}".format(node.name, node.name)) not in statusRouter or
108 host.name != node.name and ("/ndn/{}-site/{}".format(node.name, node.name)) not in statusPrefix ):
Ashlesh Gawandee144ceb2016-11-14 13:56:24 -0600109 didNodeConverge = False
110 didNlsrConverge = False
ashu34c3ee02015-03-25 14:41:14 -0500111
112 host.cmd("echo " + str(didNodeConverge) + " > convergence-result &")
113
114 if didNlsrConverge:
115 print("NLSR has successfully converged.")
116 else:
117 print("NLSR has not converged. Exiting...")
Ashlesh Gawande3807c1b2016-08-05 16:27:02 -0500118 self.net.stop()
ashu34c3ee02015-03-25 14:41:14 -0500119 sys.exit(1)
120
121 def startPings(self):
122 for host in self.net.hosts:
123 for other in self.net.hosts:
124 # Do not ping self
125 if host.name != other.name:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500126 NDNPingClient.ping(host, other, self.options.nPings)
ashu34c3ee02015-03-25 14:41:14 -0500127
Vince Lehmand96eed32015-10-22 13:57:27 -0500128 def failNode(self, host):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500129 print("Bringing {} down".format(host.name))
Vince Lehmand96eed32015-10-22 13:57:27 -0500130 host.nfd.stop()
131
132 def recoverNode(self, host):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500133 print("Bringing {} up".format(host.name))
Vince Lehmand96eed32015-10-22 13:57:27 -0500134 host.nfd.start()
Ashlesh Gawande708fcca2017-06-23 14:04:12 -0500135 host.nlsr.createFaces()
Vince Lehmand96eed32015-10-22 13:57:27 -0500136 host.nlsr.start()
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500137 Nfdc.setStrategy(host, "/ndn/", self.options.strategy)
138 host.cmd("ndnpingserver /ndn/{}-site/{} > ping-server &".format(host.name, host.name))
Vince Lehmand96eed32015-10-22 13:57:27 -0500139
Ashlesh Gawanded9c9e522015-10-15 16:40:12 -0500140 def startPctPings(self):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500141 nNodesToPing = int(round(len(self.net.hosts) * self.options.pctTraffic))
142 print "Each node will ping {} node(s)".format(nNodesToPing)
Ashlesh Gawanded9c9e522015-10-15 16:40:12 -0500143 # Temporarily store all the nodes being pinged by a particular node
144 nodesPingedList = []
145
146 for host in self.net.hosts:
147 # Create a circular list
148 pool = cycle(self.net.hosts)
149
150 # Move iterator to current node
151 next(x for x in pool if host.name == x.name)
152
153 # Track number of nodes to ping scheduled for this node
154 nNodesScheduled = 0
155
156 while nNodesScheduled < nNodesToPing:
157 other = pool.next()
158
159 # Do not ping self
160 if host.name != other.name:
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500161 NDNPingClient.ping(host, other, self.options.nPings)
Ashlesh Gawanded9c9e522015-10-15 16:40:12 -0500162 nodesPingedList.append(other)
163
164 # Always increment because in 100% case a node should not ping itself
165 nNodesScheduled = nNodesScheduled + 1
166
167 self.pingedDict[host] = nodesPingedList
168 nodesPingedList = []
169
Vince Lehman3b8bc652015-06-18 15:01:47 -0500170 @staticmethod
171 def register(name, experimentClass):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500172 ExperimentManager.register(name, experimentClass)