2 * Copyright (c) 2007-2008 Fabrizio Frioli, Michele Pedrolli
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * Please send your questions/suggestions to:
20 * {fabrizio.frioli, michele.pedrolli} at studenti dot unitn dot it
24 package example.bittorrent;
26 import peersim.config.*;
27 import peersim.core.*;
28 import peersim.transport.*;
29 import peersim.edsim.*;
32 * This {@link Control} can change the size of networks by adding and removing
33 * nodes. This class supports only permanent removal of nodes and the addition
34 * of brand new nodes. That is, temporary downtime is not supported by this
37 public class NetworkDynamics implements Control {
38 private static final int TRACKER = 11;
39 private static final int CHOKE_TIME = 13;
40 private static final int OPTUNCHK_TIME = 14;
41 private static final int ANTISNUB_TIME = 15;
42 private static final int CHECKALIVE_TIME = 16;
43 private static final int TRACKERALIVE_TIME = 17;
46 * The protocol to operate on.
50 private static final String PAR_PROT = "protocol";
53 * Nodes are removed until the size specified by this parameter is reached.
54 * The network will never go below this size as a result of this class.
59 private static final String PAR_MIN = "minsize";
62 * Specifies if the tracker can disappear from the network. 0 means no, 1
67 private static final String PAR_TRACKER_DIE = "tracker_can_die";
70 * The Transport used by the the control.
74 private static final String PAR_TRANSPORT = "transport";
77 * Specifies how many nodes will be added to the network.
81 private static final String PAR_ADD = "add";
84 * Specifies how many nodes will be removed from the network.
88 private static final String PAR_REMOVE = "remove";
91 * The following are local variables, obtained from config property.
93 private final int pid;
94 private final int tid;
95 private final int maxSize;
96 private final int minsize;
97 private boolean trackerCanDie = false; // false (value 0) by default
98 private final int add; // number of nodes to be added
99 private final int remove; // number of nodes to be removed
101 private final NodeInitializer init;
102 private Node tracker;
105 * Standard constructor that reads the configuration parameters. Invoked by
106 * the simulation engine.
109 * the configuration prefix for this class
111 public NetworkDynamics(String prefix) {
112 pid = Configuration.getPid(prefix + "." + PAR_PROT);
113 minsize = Configuration.getInt(prefix + "." + PAR_MIN, 0);
114 tid = Configuration.getPid(prefix + "." + PAR_TRANSPORT);
115 add = Configuration.getInt(prefix + "." + PAR_ADD);
116 remove = Configuration.getInt(prefix + "." + PAR_REMOVE);
119 * By default, the tracker can not disappear. If
120 * control.dynamics.tracker_can_die is set to 1, the tracker can die.
122 if (Configuration.getInt(prefix + "." + PAR_TRACKER_DIE) == 1) {
123 trackerCanDie = true;
126 init = new NodeInitializer("init.net");
127 tracker = Network.get(0);
129 maxSize = (Network.size() - 1)
130 + ((BitTorrent) tracker.getProtocol(pid)).maxGrowth;
134 * Adds n nodes to the network. New nodes can be added only if the tracker
138 * the number of nodes to add, must be non-negative.
140 protected void add(int n) {
144 if (tracker.isUp()) {
145 for (int i = 0; i < n; ++i) {
147 Node nodeToBeAdded = (Node) Network.prototype.clone();
149 // add the new node to the network
150 Network.add(nodeToBeAdded); // questo nodo sara' in posizione
154 * Initialize the new node using the NodeInitializer class; this
156 * init.initialize(Network.get(Network.size()-1));
158 init.initialize(nodeToBeAdded);
161 * The new node sends a TRACKER message to the tracker, asking
162 * for a list of peers. The tracker will respond with a PEERSET
163 * message. All the related events are also attached to the new
166 long latency =((Transport)nodeToBeAdded.getProtocol(tid)).getLatency(nodeToBeAdded,tracker);
167 Object ev = new SimpleMsg(TRACKER, nodeToBeAdded);
168 EDSimulator.add(latency,ev,tracker,pid);
169 // ((Transport) nodeToBeAdded.getProtocol(tid)).send(
170 // nodeToBeAdded, tracker, ev, pid);
172 ev = new SimpleEvent(CHOKE_TIME);
173 EDSimulator.add(10000, ev, nodeToBeAdded, pid);
174 ev = new SimpleEvent(OPTUNCHK_TIME);
175 EDSimulator.add(30000, ev, nodeToBeAdded, pid);
176 ev = new SimpleEvent(ANTISNUB_TIME);
177 EDSimulator.add(60000, ev, nodeToBeAdded, pid);
178 ev = new SimpleEvent(CHECKALIVE_TIME);
179 EDSimulator.add(120000, ev, nodeToBeAdded, pid);
180 ev = new SimpleEvent(TRACKERALIVE_TIME);
181 EDSimulator.add(1800000, ev, nodeToBeAdded, pid);
183 // add the new node to the tracker's cache
184 if (((BitTorrent) tracker.getProtocol(pid))
185 .addNeighbor(nodeToBeAdded))
187 .println("DYN: A new node has been added to the network.");
191 * Otherwise, the tracker is down and no new nodes can be added to the
195 System.out.println("DYN: Tracker is down. No new nodes added.");
199 * Removes n nodes from the network. A node can be removed either if the
200 * tracker is up or down; if the tracker is up, the node to be removed will
201 * be removed also from the tracker's cache.
204 * the number of nodes to remove.
206 protected void remove(int n) {
207 // the index of the node to be removed
210 for (int i = 0; i < n; ++i) {
211 nodeIndex = CommonState.r.nextInt(Network.size());
212 // if the tracker can not disappear from the network
213 if (!trackerCanDie) {
215 * Choose an index for the node to be removed. The value 0 will
216 * be discarded, since the tracker cannot disappear. Non
217 * existing nodes cannot be removed: if the returned index
218 * corresponds to a non-existing node, a new index will be
221 while (nodeIndex == 0) {
222 nodeIndex = CommonState.r.nextInt(Network.size());
225 // otherwise, also the tracker can disappear
227 nodeIndex = CommonState.r.nextInt(Network.size());
232 // System.out.println("DYN: The tracker is going to disapper.");
234 // remove the node with the given index from the network
235 Node nodeToBeRemoved = Network.remove(nodeIndex);
237 // then remove it from the tracker's cache, if it is possible (= the
239 if (tracker.isUp()) {
240 if (((BitTorrent) tracker.getProtocol(pid))
241 .removeNeighbor(nodeToBeRemoved))
243 .println("DYN: A node has been removed from the network.");
244 } else { // the tracker is down
245 System.err.println("DYN: The tracker is DOWN!");
251 * Calls {@link #add(int)} or {@link #remove} with the parameters defined by
254 * @return always false
256 public boolean execute() {
257 int choice = (CommonState.r.nextInt(2)); // 0 or 1
261 * If the specified number of nodes cannot be added, it tries to add
262 * a less number of nodes without going out of bounds. Otherwise,
263 * all specified nodes will be added.
265 if (Network.size() + this.add > maxSize) {
266 System.err.println("DYN: " + (maxSize - Network.size())
267 + " nodes will be added.");
268 add(maxSize - Network.size());
271 .println("DYN: " + this.add + " nodes will be added.");
275 // removing existing nodes
277 if (Network.size() - this.remove < minsize) {
278 System.err.println("DYN: " + (Network.size() - minsize)
279 + " nodes will be removed.");
280 remove(Network.size() - minsize);
282 System.err.println("DYN: " + this.remove
283 + " nodes will be removed.");