OverSim
MyOverlay.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2009 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
23 #include <iostream>
24 
25 #include <UnderlayConfigurator.h>
26 #include <GlobalStatistics.h>
27 
28 #include "MyOverlay_m.h"
29 
30 #include "MyOverlay.h"
31 
32 
33 // Important! This line must be present for each module you extend (see BaseApp)
35 
36 // To convert between IP addresses (which have bit 24 active), and keys (which don't), we'll need to set or remove this bit.
37 #define BIGBIT (1 << 24)
38 
39 
40 // Called when the module is being initialized
42 {
43  // see BaseApp.cc
44  if (stage != MIN_STAGE_OVERLAY) return;
45 
46  // get our key from our IP address
47  myKey = thisNode.getIp().get4().getInt() & ~BIGBIT;
48 
49  // initialize the rest of variables
50  numDropped = 0;
51  if (!(par("enableDrops"))) {
52  dropChance = 0;
53  } else {
54  dropChance = par("dropChance");
55  }
56 
57  rpcTimer = new cMessage("RPC timer");
58  scheduleAt(simTime() + 5, rpcTimer);
59 }
60 
61 // Called to set our own overlay key (optional)
63 {
64  // create the corresponding overlay key
66 }
67 
68 
69 // Called when the module is ready to join the overlay
71 {
72  // Set the information of the previous step in the chain
73  prevNode.setIp(IPAddress(BIGBIT | (myKey - 1)));
76 
77  // Set the information of the next step in the chain
78  nextNode.setIp(IPAddress(BIGBIT | (myKey + 1)));
81 
82  // tell the simulator that we're ready
83  setOverlayReady(true);
84 }
85 
86 void MyOverlay::handleTimerEvent(cMessage *msg)
87 {
88  if (msg == rpcTimer) {
89  // reschedule the timer
90  scheduleAt(simTime() + 5, rpcTimer);
91 
92  // if the simulator is still busy creating the network, let's wait a bit longer
93  if (underlayConfigurator->isInInitPhase()) return;
94 
95  // pick either or next neighbor, or our previous neighbor, and request their neighbors
96  OverlayKey key;
97  int neighborToAsk = intuniform(0, 1);
98 
99  if (neighborToAsk == 0) key = prevNode.getKey();
100  else key = nextNode.getKey();
101 
102  getNeighbors(key);
103  }
104 }
105 
106 // Return whether the given node is responsible for the key
108  const OverlayKey& key,
109  int numSiblings,
110  bool* err)
111 {
112  // is it our node and our key?
113  if (node == thisNode && key == thisNode.getKey()) {
114  return true;
115  }
116  // we don't know otherwise
117  return false;
118 }
119 
120 // Return the next step for the routing of the given message
122  int numRedundantNodes,
123  int numSiblings,
124  BaseOverlayMessage* msg)
125 {
126  NodeVector* nextHops;
127 
128  // do we drop the packet?
129  if (uniform(0, 1) < dropChance) {
130  // if yes, return an empty node vector
131  nextHops = new NodeVector(0);
132  numDropped++;
133  return nextHops;
134  }
135 
136  // else, set the response vector with one node
137  nextHops = new NodeVector(1);
138 
139  // are we responsible? next step is this node
140  if (key == thisNode.getKey()) {
141  nextHops->add(thisNode);
142  }
143  // is the key behind us? next step is the previous node
144  else if (key < thisNode.getKey()) {
145  nextHops->add(prevNode);
146  }
147  // otherwise, the next step is the next node
148  else {
149  nextHops->add(nextNode);
150  }
151  return nextHops;
152 }
153 
154 // Called when the module is about to be destroyed
156 {
157  // remove this node from the overlay
158  setOverlayReady(false);
159 
160  // save the statistics (see BaseApp)
161  globalStatistics->addStdDev("MyOverlay: Dropped packets", numDropped);
162 }
163 
164 // Return the max amount of siblings that can be queried about
166 {
167  return 1;
168 }
169 
170 // Return the max amount of redundant that can be queried about
172 {
173  return 1;
174 }
175 
176 
177 void MyOverlay::getNeighbors(const OverlayKey &neighborKey)
178 {
179  MyNeighborCall *msg = new MyNeighborCall();
180  msg->setDestinationKey(neighborKey);
181 
182  // The function we'll be using to send an RPC is sendRouteRpcCall.
183  // The first value is to which tier we'll be talking. Can be either
184  // OVERLAY_COMP, TIER1_COMP, TIER2_COMP, and so on.
185  // The second parameter is the node to which we'll send the message.
186  // Can be either an OverlayKey or a TransportAddress.
187  // The third parameter is the message.
188 
189  EV << thisNode << ": (RPC) Sending query to "
190  << neighborKey << "!" << std::endl;
191 
192  sendRouteRpcCall(OVERLAY_COMP, neighborKey, msg);
193 }
194 
195 // Handle an incoming Call message
196 // Only delete msg if the RPC is handled here, and you won't respond using sendRpcResponse!
198 {
199  // There are many macros to simplify the handling of RPCs. The full list is in <OverSim>/src/common/RpcMacros.h.
200 
201  // start a switch
202  RPC_SWITCH_START(msg);
203 
204  // enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
205  RPC_ON_CALL(MyNeighbor) {
206  // get Call message
207  MyNeighborCall *mrpc = (MyNeighborCall*)msg;
208 
209  // create response
212  rrpc->setPrevNeighbor(prevNode);
213  rrpc->setNextNeighbor(nextNode);
214 
215  // now send the response. sendRpcResponse can automatically tell where
216  // to send it to. Note that sendRpcResponse will delete mrpc (aka msg)!
217  sendRpcResponse(mrpc, rrpc);
218 
219  RPC_HANDLED = true; // set to true, since we did handle this RPC (default is false)
220  }
221 
222  // end the switch
223  RPC_SWITCH_END();
224 
225  // return whether we handled the message or not.
226  // don't delete unhandled messages!
227  return RPC_HANDLED;
228 }
229 
230 // Called when an RPC we sent has timed out.
231 // Don't delete msg here!
232 
234  const TransportAddress& dest,
235  cPolymorphic* context, int rpcId,
236  const OverlayKey&)
237 {
238  // Same macros as in handleRpc
239 
240  // start a switch
241  RPC_SWITCH_START(msg);
242 
243  // enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
244  RPC_ON_CALL(MyNeighbor) {
245  MyNeighborCall *mrpc = (MyNeighborCall*)msg; // get Call message
246  callbackTimeout(mrpc->getDestinationKey()); // call interface function
247  }
248  // end the switch
249  RPC_SWITCH_END();
250 }
251 
252 // Called when we receive an RPC response from another node.
253 // Don't delete msg here!
254 
256  cPolymorphic* context,
257  int rpcId,
258  simtime_t rtt)
259 {
260  // The macros are here similar. Just use RPC_ON_RESPONSE instead of RPC_ON_CALL.
261 
262  // start a switch
263  RPC_SWITCH_START(msg);
264 
265  // enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
266  RPC_ON_RESPONSE(MyNeighbor) {
267  // get Response message
269  // call our interface function
271  mrpc->getPrevNeighbor(),
272  mrpc->getNextNeighbor());
273  }
274  // end the switch
275  RPC_SWITCH_END();
276 }
277 
278 void MyOverlay::callbackNeighbors(const NodeHandle& neighborKey,
279  const NodeHandle& prevNeighbor,
280  const NodeHandle& nextNeighbor)
281 {
282  EV << thisNode << ": (RPC) Got response from "
283  << neighborKey << "\n"
284  << thisNode << ": (RPC) Neighbors: "
285  << prevNeighbor.getIp() << ", "
286  << nextNeighbor.getIp() << std::endl;
287 }
288 
289 void MyOverlay::callbackTimeout(const OverlayKey &neighborKey)
290 {
291  EV << thisNode << ": (RPC) Query to " << neighborKey
292  << " timed out!" << std::endl;
293 }