OverSim
BaseOverlay.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2006 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 
28 #include <cassert>
29 
30 #include <RpcMacros.h>
31 
32 #include <UDPAppBase.h>
33 #include <UDPSocket.h>
34 #include <IPAddressResolver.h>
35 #include <NotificationBoard.h>
36 
37 #include <GlobalNodeListAccess.h>
39 #include <GlobalStatisticsAccess.h>
40 #include <GlobalParametersAccess.h>
41 
42 #include <LookupListener.h>
43 #include <RecursiveLookup.h>
44 #include <IterativeLookup.h>
45 
46 #include <BootstrapList.h>
47 
48 #include "BaseOverlay.h"
49 
50 using namespace std;
51 
52 
53 //------------------------------------------------------------------------
54 //--- Initialization & finishing -----------------------------------------
55 //------------------------------------------------------------------------
56 
58 {
59  globalNodeList = NULL;
60  underlayConfigurator = NULL;
61  notificationBoard = NULL;
62  globalParameters = NULL;
63  bootstrapList = NULL;
64 }
65 
67 {
68  finishLookups();
69  finishRpcs();
70 }
71 
73 {
74  return NUM_STAGES_ALL;
75 }
76 
77 void BaseOverlay::initialize(int stage)
78 {
79  if (stage == 0) {
80  OverlayKey::setKeyLength(par("keyLength"));
81  }
82 
83  if (stage == REGISTER_STAGE) {
84  registerComp(getThisCompType(), this);
85  return;
86  }
87 
88  if (stage == MIN_STAGE_OVERLAY) {
89  // find friend modules
90  globalNodeList = GlobalNodeListAccess().get();
91  underlayConfigurator = UnderlayConfiguratorAccess().get();
92  notificationBoard = NotificationBoardAccess().get();
93  globalParameters = GlobalParametersAccess().get();
94  bootstrapList = check_and_cast<BootstrapList*>(getParentModule()->
95  getParentModule()->getSubmodule("bootstrapList", 0));
96 
97  udpGate = gate("udpIn");
98  appGate = gate("appIn");
99 
100  // fetch some parameters
101  overlayId = par ("overlayId");
102  debugOutput = par("debugOutput");
103  collectPerHopDelay = par("collectPerHopDelay");
104  localPort = par("localPort");
105  hopCountMax = par("hopCountMax");
106  drawOverlayTopology = par("drawOverlayTopology");
107  rejoinOnFailure = par("rejoinOnFailure");
108  sendRpcResponseToLastHop = par("sendRpcResponseToLastHop");
109  dropFindNodeAttack = par("dropFindNodeAttack");
110  isSiblingAttack = par("isSiblingAttack");
111  invalidNodesAttack = par("invalidNodesAttack");
112  dropRouteMessageAttack = par("dropRouteMessageAttack");
113  measureAuthBlock = par("measureAuthBlock");
114  restoreContext = par("restoreContext");
115 
116  // we assume most overlays don't provide KBR services
117  kbr = false;
118 
119  // set routing type
120  std::string temp = par("routingType").stdstringValue();
121  if (temp == "iterative")
122  defaultRoutingType = ITERATIVE_ROUTING;
123  else if (temp == "exhaustive-iterative")
124  defaultRoutingType = EXHAUSTIVE_ITERATIVE_ROUTING;
125  else if (temp == "semi-recursive")
126  defaultRoutingType = SEMI_RECURSIVE_ROUTING;
127  else if (temp == "full-recursive")
128  defaultRoutingType = FULL_RECURSIVE_ROUTING;
129  else if (temp == "source-routing-recursive")
130  defaultRoutingType = RECURSIVE_SOURCE_ROUTING;
131  else throw cRuntimeError((std::string("Wrong routing type: ")
132  + temp).c_str());
133 
134  useCommonAPIforward = par("useCommonAPIforward");
135  routeMsgAcks = par("routeMsgAcks");
136  recNumRedundantNodes = par("recNumRedundantNodes");
137  recordRoute = par("recordRoute");
138 
139  // set base lookup parameters
140  iterativeLookupConfig.redundantNodes = par("lookupRedundantNodes");
141  iterativeLookupConfig.parallelPaths = par("lookupParallelPaths");
142  iterativeLookupConfig.parallelRpcs = par("lookupParallelRpcs");
143  iterativeLookupConfig.verifySiblings = par("lookupVerifySiblings");
144  iterativeLookupConfig.majoritySiblings = par("lookupMajoritySiblings");
145  iterativeLookupConfig.merge = par("lookupMerge");
146  iterativeLookupConfig.failedNodeRpcs = par("lookupFailedNodeRpcs");
147  iterativeLookupConfig.strictParallelRpcs =
148  par("lookupStrictParallelRpcs");
149  iterativeLookupConfig.useAllParallelResponses =
150  par("lookupUseAllParallelResponses");
151  iterativeLookupConfig.newRpcOnEveryTimeout =
152  par("lookupNewRpcOnEveryTimeout");
153  iterativeLookupConfig.newRpcOnEveryResponse =
154  par("lookupNewRpcOnEveryResponse");
155  iterativeLookupConfig.finishOnFirstUnchanged =
156  par("lookupFinishOnFirstUnchanged");
157  iterativeLookupConfig.visitOnlyOnce =
158  par("lookupVisitOnlyOnce");
159  iterativeLookupConfig.acceptLateSiblings =
160  par("lookupAcceptLateSiblings");
161 
162  recursiveLookupConfig.redundantNodes = par("lookupRedundantNodes");
163  recursiveLookupConfig.numRetries = 0; //TODO
164 
165  // statistics
166  numAppDataSent = 0;
167  bytesAppDataSent = 0;
168  numAppLookupSent = 0;
169  bytesAppLookupSent = 0;
170  numMaintenanceSent = 0;
171  bytesMaintenanceSent = 0;
172  numAppDataReceived = 0;
173  bytesAppDataReceived = 0;
174  numAppLookupReceived = 0;
175  bytesAppLookupReceived = 0;
176  numMaintenanceReceived = 0;
177  bytesMaintenanceReceived = 0;
178  numAppDataForwarded = 0;
179  bytesAppDataForwarded = 0;
180  numAppLookupForwarded = 0;
181  bytesAppLookupForwarded = 0;
182  numMaintenanceForwarded = 0;
183  bytesMaintenanceForwarded = 0;
184  bytesAuthBlockSent = 0;
185 
186  numDropped = 0;
187  bytesDropped = 0;
188  numFindNodeSent = 0;
189  bytesFindNodeSent = 0;
190  numFindNodeResponseSent = 0;
191  bytesFindNodeResponseSent = 0;
192  numFailedNodeSent = 0;
193  bytesFailedNodeSent = 0;
194  numFailedNodeResponseSent = 0;
195  bytesFailedNodeResponseSent = 0;
196 
197  joinRetries = 0;
198 
199  numInternalSent = 0;
200  bytesInternalSent = 0;
201  numInternalReceived = 0;
202  bytesInternalReceived = 0;
203 
204  WATCH(numAppDataSent);
205  WATCH(bytesAppDataSent);
206  WATCH(numAppLookupSent);
207  WATCH(bytesAppLookupSent);
208  WATCH(numMaintenanceSent);
209  WATCH(bytesMaintenanceSent);
210  WATCH(numAppDataReceived);
211  WATCH(bytesAppDataReceived);
212  WATCH(numAppLookupReceived);
213  WATCH(bytesAppLookupReceived);
214  WATCH(numMaintenanceReceived);
215  WATCH(bytesMaintenanceReceived);
216  WATCH(numAppDataForwarded);
217  WATCH(bytesAppDataForwarded);
218  WATCH(numAppLookupForwarded);
219  WATCH(bytesAppLookupForwarded);
220  WATCH(numMaintenanceForwarded);
221  WATCH(bytesMaintenanceForwarded);
222 
223  WATCH(numDropped);
224  WATCH(bytesDropped);
225  WATCH(numFindNodeSent);
226  WATCH(bytesFindNodeSent);
227  WATCH(numFindNodeResponseSent);
228  WATCH(bytesFindNodeResponseSent);
229  WATCH(numFailedNodeSent);
230  WATCH(bytesFailedNodeSent);
231  WATCH(numFailedNodeResponseSent);
232  WATCH(bytesFailedNodeResponseSent);
233 
234  WATCH(joinRetries);
235 
236  if (isInSimpleMultiOverlayHost()) {
237  WATCH(numInternalSent);
238  WATCH(bytesInternalSent);
239  WATCH(numInternalReceived);
240  WATCH(bytesInternalReceived);
241  }
242 
243  // set up local nodehandle
244  thisNode.setIp(IPAddressResolver().
245  addressOf(getParentModule()->getParentModule()));
246  thisNode.setKey(OverlayKey::UNSPECIFIED_KEY);
247 
248  state = INIT;
249  internalReadyState = false;
250 
251  getDisplayString().setTagArg("i", 1, "red");
252  globalNodeList->setOverlayReadyIcon(getThisNode(), false);
253 
254  // set up UDP
255  bindToPort(localPort);
256 
257  // subscribe to the notification board
258  notificationBoard->subscribe(this, NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
259  notificationBoard->subscribe(this, NF_OVERLAY_NODE_LEAVE);
260  notificationBoard->subscribe(this, NF_OVERLAY_NODE_GRACEFUL_LEAVE);
261 
262  // init visualization with terminal ptr
263  if (drawOverlayTopology)
264  initVis(getParentModule()->getParentModule());
265 
266  // init rpcs
267  initRpcs();
268  initLookups();
269 
270  // set TCP output gate
271  setTcpOut(gate("tcpOut"));
272 
273  // statistics
274  creationTime = simTime();
275  WATCH(creationTime);
276  }
277 
278  if (stage >= MIN_STAGE_OVERLAY && stage <= MAX_STAGE_OVERLAY)
279  initializeOverlay(stage);
280 
281  if (stage == MAX_STAGE_TIER_1) {
282  // bootstrapList registered its gate to the overlay 0
283  // if this is not overlay 0, we may not have the gate, so retrieve it
284  // this assumes that the overlay is in a container module!
285  if (!compModuleList.count(BOOTSTRAPLIST_COMP)) {
286  BaseOverlay *firstOverlay = dynamic_cast<BaseOverlay*>
287  (getParentModule()->getParentModule()
288  ->getSubmodule("overlay", 0)->gate("appIn")
289  ->getNextGate()->getOwnerModule());
290  if (!firstOverlay) {
291  throw cRuntimeError("BaseOverlay.cc: "
292  "Couldn't obtain bootstrap gate");
293  }
294  registerComp(BOOTSTRAPLIST_COMP,
295  firstOverlay->getCompModule(BOOTSTRAPLIST_COMP));
296  }
297  }
298 }
299 
300 
302 {
303 }
304 
306 {
307  finishOverlay();
308 
309  simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
310 
311  if (time >= GlobalStatistics::MIN_MEASURED) {
312 
313  if (collectPerHopDelay) {
314  std::ostringstream singleHopName;
315  HopDelayRecord* hdrl = NULL;
316  HopDelayRecord* hdr = NULL;
317  for (size_t i = 0; i < singleHopDelays.size();) {
318  hdrl = singleHopDelays[i++];
319  hdr = hdrl;
320  for (size_t j = 1; j <= i; ++j) {
321  if (hdr->count == 0) continue;
322  singleHopName.str("");
323  singleHopName << "BaseOverlay: Average Delay in Hop "
324  << j << " of " << i;
325  globalStatistics->addStdDev(singleHopName.str(),
326  SIMTIME_DBL(hdr->val / hdr->count));
327  ++hdr;
328  }
329  delete[] hdrl;
330  }
331  singleHopDelays.clear();
332  }
333 
334  globalStatistics->addStdDev("BaseOverlay: Join Retries", joinRetries);
335 
336  globalStatistics->addStdDev("BaseOverlay: Sent App Data Messages/s",
337  numAppDataSent / time);
338  globalStatistics->addStdDev("BaseOverlay: Sent App Data Bytes/s",
339  bytesAppDataSent / time);
340  if (isInSimpleMultiOverlayHost()) {
341  globalStatistics->addStdDev("BaseOverlay: Internal Sent Messages/s",
342  numInternalReceived / time);
343  globalStatistics->addStdDev("BaseOverlay: Internal Sent Bytes/s",
344  bytesInternalReceived / time);
345  }
346  globalStatistics->addStdDev("BaseOverlay: Sent App Lookup Messages/s",
347  numAppLookupSent / time);
348  globalStatistics->addStdDev("BaseOverlay: Sent App Lookup Bytes/s",
349  bytesAppLookupSent / time);
350  globalStatistics->addStdDev("BaseOverlay: Sent Maintenance Messages/s",
351  numMaintenanceSent / time);
352  globalStatistics->addStdDev("BaseOverlay: Sent Maintenance Bytes/s",
353  bytesMaintenanceSent / time);
354 
355  globalStatistics->addStdDev("BaseOverlay: Sent Total Messages/s",
356  (numAppDataSent + numAppLookupSent +
357  numMaintenanceSent) / time);
358  globalStatistics->addStdDev("BaseOverlay: Sent Total Bytes/s",
359  (bytesAppDataSent + bytesAppLookupSent +
360  bytesMaintenanceSent) / time);
361  globalStatistics->addStdDev("BaseOverlay: Sent FindNode Messages/s",
362  numFindNodeSent / time);
363  globalStatistics->addStdDev("BaseOverlay: Sent FindNode Bytes/s",
364  bytesFindNodeSent / time);
365 
366  globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Messages/s",
367  numFindNodeResponseSent / time);
368  globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Bytes/s",
369  bytesFindNodeResponseSent / time);
370  globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Messages/s",
371  numFailedNodeSent / time);
372  globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Bytes/s",
373  bytesFailedNodeSent / time);
374  globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Messages/s",
375  numFailedNodeResponseSent / time);
376  globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Bytes/s",
377  bytesFailedNodeResponseSent / time);
378  globalStatistics->addStdDev("BaseOverlay: Received App Data Messages/s",
379  numAppDataReceived / time);
380  globalStatistics->addStdDev("BaseOverlay: Received App Data Bytes/s",
381  bytesAppDataReceived / time);
382  if (isInSimpleMultiOverlayHost()) {
383  globalStatistics->addStdDev("BaseOverlay: Internal Received Messages/s",
384  numInternalReceived / time);
385  globalStatistics->addStdDev("BaseOverlay: Internal Received Bytes/s",
386  bytesInternalReceived / time);
387  }
388  globalStatistics->addStdDev("BaseOverlay: Received App Lookup Messages/s",
389  numAppLookupReceived / time);
390  globalStatistics->addStdDev("BaseOverlay: Received App Lookup Bytes/s",
391  bytesAppLookupReceived / time);
392  globalStatistics->addStdDev("BaseOverlay: Received Maintenance Messages/s",
393  numMaintenanceReceived / time);
394  globalStatistics->addStdDev("BaseOverlay: Received Maintenance Bytes/s",
395  bytesMaintenanceReceived / time);
396 
397  globalStatistics->addStdDev("BaseOverlay: Received Total Messages/s",
398  (numAppDataReceived + numAppLookupReceived +
399  numMaintenanceReceived)/time);
400  globalStatistics->addStdDev("BaseOverlay: Received Total Bytes/s",
401  (bytesAppDataReceived + bytesAppLookupReceived +
402  bytesMaintenanceReceived)/time);
403  globalStatistics->addStdDev("BaseOverlay: Forwarded App Data Messages/s",
404  numAppDataForwarded / time);
405  globalStatistics->addStdDev("BaseOverlay: Forwarded App Data Bytes/s",
406  bytesAppDataForwarded / time);
407  globalStatistics->addStdDev("BaseOverlay: Forwarded App Lookup Messages/s",
408  numAppLookupForwarded / time);
409  globalStatistics->addStdDev("BaseOverlay: Forwarded App Lookup Bytes/s",
410  bytesAppLookupForwarded / time);
411  globalStatistics->addStdDev("BaseOverlay: Forwarded Maintenance Messages/s",
412  numMaintenanceForwarded / time);
413  globalStatistics->addStdDev("BaseOverlay: Forwarded Maintenance Bytes/s",
414  bytesMaintenanceForwarded / time);
415  globalStatistics->addStdDev("BaseOverlay: Forwarded Total Messages/s",
416  (numAppDataForwarded + numAppLookupForwarded +
417  numMaintenanceForwarded) / time);
418  globalStatistics->addStdDev("BaseOverlay: Forwarded Total Bytes/s",
419  (bytesAppDataForwarded + bytesAppLookupForwarded +
420  bytesMaintenanceForwarded) / time);
421 
422  globalStatistics->addStdDev("BaseOverlay: Dropped Messages/s",
423  numDropped / time);
424  globalStatistics->addStdDev("BaseOverlay: Dropped Bytes/s",
425  bytesDropped / time);
426 
427  globalStatistics->addStdDev("BaseOverlay: Measured Session Time",
428  SIMTIME_DBL(simTime() - creationTime));
429 
430  globalStatistics->addStdDev("BaseOverlay: Sent Ping Messages/s",
431  numPingSent / time);
432  globalStatistics->addStdDev("BaseOverlay: Sent Ping Bytes/s",
433  bytesPingSent / time);
434  globalStatistics->addStdDev("BaseOverlay: Sent Ping Response Messages/s",
435  numPingResponseSent / time);
436  globalStatistics->addStdDev("BaseOverlay: Sent Ping Response Bytes/s",
437  bytesPingResponseSent / time);
438 
439  if (getMeasureAuthBlock()) {
440  globalStatistics->addStdDev("BaseOverlay: Sent AuthBlock Bytes/s",
441  bytesAuthBlockSent / time);
442  }
443  }
444 }
445 
447 {
448 }
449 
450 //------------------------------------------------------------------------
451 //--- General Overlay Parameters (getter and setters) --------------------
452 //------------------------------------------------------------------------
454 {
455  return globalNodeList->isMalicious(getThisNode());
456 }
457 
459 {
460  return OVERLAY_COMP;
461 }
462 
463 //------------------------------------------------------------------------
464 //--- UDP functions copied from the INET framework .----------------------
465 //------------------------------------------------------------------------
467 {
468  EV << "[BaseOverlay::bindToPort() @ " << thisNode.getIp()
469  << " (" << thisNode.getKey().toString(16) << ")]\n"
470  << " Binding to UDP port " << port
471  << endl;
472 
473  thisNode.setPort(port);
474 
475  // TODO UDPAppBase should be ported to use UDPSocket sometime, but for now
476  // we just manage the UDP socket by hand...
477  cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
478  socketId = UDPSocket::generateSocketId();
479  UDPControlInfo *ctrl = new UDPControlInfo();
480  ctrl->setSrcPort(port);
481  ctrl->setSockId(socketId);
482  msg->setControlInfo(ctrl);
483  send(msg, "udpOut");
484 }
485 
486 
487 //------------------------------------------------------------------------
488 //--- Overlay Common API: Key-based Routing ------------------------------
489 //------------------------------------------------------------------------
490 
492  const OverlayKey& destKey)
493 {
494  KBRdeliver* deliverMsg = new KBRdeliver();
495 
496  OverlayCtrlInfo* overlayCtrlInfo =
497  check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
498 
499  BaseAppDataMessage* appDataMsg = dynamic_cast<BaseAppDataMessage*>(msg);
500 
501  // TODO GIA
502  if (appDataMsg != NULL) {
503  overlayCtrlInfo->setSrcComp(appDataMsg->getSrcComp());
504  overlayCtrlInfo->setDestComp(appDataMsg->getDestComp());
505  }
506 
507  deliverMsg->setControlInfo(overlayCtrlInfo);
508  deliverMsg->setDestKey(destKey);
509  deliverMsg->encapsulate(msg->decapsulate());
510  deliverMsg->setType(KBR_DELIVER);
511 
512  cGate* destGate = getCompRpcGate(static_cast<CompType>(
513  overlayCtrlInfo->getDestComp()));
514 
515  if (destGate == NULL) {
516  throw cRuntimeError("BaseOverlay::callDeliver(): Unknown destComp!");
517  }
518 
519  sendDirect(deliverMsg, destGate);
520 
521  delete msg;
522 }
523 
525  const NodeHandle& nextHopNode)
526 {
527  KBRforward* forwardMsg = new KBRforward();
528 
529  forwardMsg->setDestKey(msg->getDestKey());
530  forwardMsg->setNextHopNode(nextHopNode);
531  forwardMsg->encapsulate(msg->getEncapsulatedPacket()->decapsulate());
532 
533  OverlayCtrlInfo* overlayCtrlInfo =
534  new OverlayCtrlInfo();
535  overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
536  overlayCtrlInfo->setRoutingType(msg->getRoutingType());
537  overlayCtrlInfo->setHopCount(msg->getHopCount());
538  overlayCtrlInfo->setSrcNode(msg->getSrcNode());
539  overlayCtrlInfo->setSrcComp(check_and_cast<BaseAppDataMessage*>
540  (msg->getEncapsulatedPacket())->getSrcComp());
541  overlayCtrlInfo->setDestComp(check_and_cast<BaseAppDataMessage*>
542  (msg->getEncapsulatedPacket())->getDestComp());
543 
544  if (msg->getControlInfo() != NULL) {
545  OverlayCtrlInfo* ctrlInfo =
546  check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
547 
548  overlayCtrlInfo->setLastHop(ctrlInfo->getLastHop());
549 
550  delete ctrlInfo;
551  }
552 
553  forwardMsg->setControlInfo(overlayCtrlInfo);
554 
555  forwardMsg->setType(KBR_FORWARD);
556 
557  send(forwardMsg, "appOut");
558 
559  delete msg;
560 }
561 
563  int num, bool safe)
564 {
565  Enter_Method("local_lookup()");
566 
567  if (safe == true) {
568  throw cRuntimeError("BaseOverlay::local_lookup(): "
569  "safe flag is not implemented!");
570  }
571 
572  if (num < 0) num = INT_MAX;
573  NodeVector* nodeVector = findNode(key, min(num, getMaxNumRedundantNodes()),
574  min(num,getMaxNumSiblings()));
575 
576  if (((int)nodeVector->size()) > num)
577  nodeVector->resize(num);
578 
579  return nodeVector;
580 }
581 
583 {
584  throw cRuntimeError("BaseOverlays::estimate_mean_distance(): "
585  "Function not implemented for this Overlay!");
586 }
587 
589 {
590  OverlayKey mean = estimateMeanDistance();
591  OverlayKey start = mean;
592  OverlayKey count = mean;
593  uint32_t number = 1;
594 
595  while (count >= start) {
596  number++;
597  count += mean;
598  }
599  return number;
600 }
601 
602 void BaseOverlay::join(const OverlayKey& nodeID)
603 {
604  Enter_Method("join()");
605 
606  joinRetries++;
607 
608  if (((state == READY) || (state == FAILED)) && !rejoinOnFailure) {
609  state = FAILED;
610  return;
611  }
612 
613  if (state != READY) {
614  // set nodeID and IP
615  thisNode.setIp(
616  IPAddressResolver().addressOf(getParentModule()->getParentModule()));
617 
618  if (!nodeID.isUnspecified()) {
619  thisNode.setKey(nodeID);
620  } else if (thisNode.getKey().isUnspecified()) {
621  std::string nodeIdStr = par("nodeId").stdstringValue();
622 
623  if (nodeIdStr.size()) {
624  // manual configuration of nodeId in ini file
625  thisNode.setKey(OverlayKey(nodeIdStr));
626  } else {
627  setOwnNodeID();
628  }
629  }
630  } else if (state == READY && !nodeID.isUnspecified()) { // TODO dCBR
631  cMessage *msg = new cMessage("UDP_C_UNBIND", UDP_C_UNBIND);
632  UDPControlInfo *ctrl = new UDPControlInfo();
633  ctrl->setSrcPort(thisNode.getPort());
634  ctrl->setSockId(socketId);
635  msg->setControlInfo(ctrl);
636  send(msg, "udpOut");
637  bindToPort((thisNode.getPort() + 10) % 0xFFFF); // test
638  thisNode.setKey(nodeID);
639  }
640  cObject** context = globalNodeList->getContext(getThisNode());
641  if (restoreContext && context) {
642  if (*context == NULL) {
643  *context = new BaseOverlayContext(getThisNode().getKey(),
644  isMalicious());
645  }
646  }
647 
648  joinOverlay();
649 }
650 
652 {
653  throw cRuntimeError("BaseOverlay::joinForeignPartition(): "
654  "This overlay doesn't support merging!");
655 }
656 
658 {
659  thisNode.setKey(OverlayKey::random());
660 }
661 
663 {
664  Enter_Method("neighborSet()");
665 
666  return local_lookup(thisNode.getKey(), num, false);
667 }
668 
669 void BaseOverlay::callUpdate(const NodeHandle& node, bool joined)
670 {
671  if ((!node.isUnspecified()) && (node != thisNode)) {
672  if (joined) {
673  EV << "[BaseOverlay::callUpdate() @ " << thisNode.getIp()
674  << " (" << thisNode.getKey().toString(16) << ")]\n"
675  << " (" << node << ", " << joined << ") joined"
676  << endl;
677  } else {
678  EV << "[BaseOverlay::callUpdate() @ " << thisNode.getIp()
679  << " (" << thisNode.getKey().toString(16) << ")]\n"
680  << " (" << node << ", " << joined << ") left"
681  << endl;
682  }
683  }
684 
685  KBRupdate* updateMsg = new KBRupdate("UPDATE");
686 
687  updateMsg->setNode(node);
688  updateMsg->setJoined(joined);
689 
690  updateMsg->setType(KBR_UPDATE);
691 
692  send(updateMsg, "appOut");
693 }
694 
695 bool BaseOverlay::isSiblingFor(const NodeHandle& node, const OverlayKey& key,
696  int numSiblings, bool* err)
697 {
698  Enter_Method("isSiblingFor()");
699 
700  throw cRuntimeError("isSiblingFor: Not implemented!");
701 
702  return false;
703 }
704 
706 {
707  Enter_Method("getMaxNumSiblings()");
708 
709  throw cRuntimeError("getMaxNumSiblings: Not implemented!");
710 
711  return false;
712 }
713 
715 {
716  Enter_Method("getMaxNumRedundantNodes()");
717 
718  throw cRuntimeError("getMaxNumRedundantNodes: Not implemented!");
719 
720  return false;
721 }
722 
723 
724 //------------------------------------------------------------------------
725 //--- Message Handlers ---------------------------------------------------
726 //------------------------------------------------------------------------
727 
728 //private
729 void BaseOverlay::handleMessage(cMessage* msg)
730 {
731  if (msg->getArrivalGate() == udpGate) {
732  UDPControlInfo* udpControlInfo =
733  check_and_cast<UDPControlInfo*>(msg->removeControlInfo());
734  OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo;
735  overlayCtrlInfo->setLastHop(TransportAddress(
736  udpControlInfo->getSrcAddr(),
737  udpControlInfo->getSrcPort()));
738  overlayCtrlInfo->setSrcRoute(overlayCtrlInfo->getLastHop());
739  overlayCtrlInfo->setTransportType(UDP_TRANSPORT);
740 
741  msg->setControlInfo(overlayCtrlInfo);
742  delete udpControlInfo;
743 
744  // debug message
745  if (debugOutput) {
746  EV << "[BaseOverlay:handleMessage() @ " << thisNode.getIp()
747  << " (" << thisNode.getKey().toString(16) << ")]\n"
748  << " Received " << *msg << " from "
749  << overlayCtrlInfo->getLastHop().getIp() << endl;
750  }
751 
752  BaseOverlayMessage* baseOverlayMsg =
753  dynamic_cast<BaseOverlayMessage*>(msg);
754 
755  if (baseOverlayMsg == NULL) {
756  cPacket* packet = check_and_cast<cPacket*>(msg);
757  RECORD_STATS(numDropped++; bytesDropped += packet->getByteLength());
758  delete msg;
759  return;
760  }
761 
762  // records stats if message is not a UDP "self message"
763  if (overlayCtrlInfo->getLastHop() != thisNode) {
764  // is this from anywhere else?
765  if (baseOverlayMsg->getStatType() == APP_DATA_STAT)
766  RECORD_STATS(numAppDataReceived++; bytesAppDataReceived +=
767  baseOverlayMsg->getByteLength());
768  else if (baseOverlayMsg->getStatType() == APP_LOOKUP_STAT)
769  RECORD_STATS(numAppLookupReceived++;bytesAppLookupReceived +=
770  baseOverlayMsg->getByteLength());
771  else // MAINTENANCE_STAT
772  RECORD_STATS(numMaintenanceReceived++;
773  bytesMaintenanceReceived +=
774  baseOverlayMsg->getByteLength());
775  }
776  if (overlayCtrlInfo->getLastHop().getIp() == thisNode.getIp()) {
777  // is this from the same node?
778  RECORD_STATS(numInternalReceived++; bytesInternalReceived +=
779  baseOverlayMsg->getByteLength());
780  } else overlayCtrlInfo->setHopCount(1);
781 
782  // process rpc calls/responses or BaseOverlayMessages
783  if (!internalHandleMessage(msg)) {
784  handleBaseOverlayMessage(baseOverlayMsg);
785  }
786  }
787 
788  // process timer events and rpc timeouts
789  else if (internalHandleMessage(msg)) return;
790 
791  // process CommonAPIMessages from App
792  else if (dynamic_cast<CommonAPIMessage*>(msg) != NULL) {
793  if (dynamic_cast<KBRroute*>(msg) != NULL) {
794  KBRroute* apiMsg = static_cast<KBRroute*>(msg);
795 
796  std::vector<TransportAddress> sourceRoute;
797  for (uint32_t i = 0; i < apiMsg->getSourceRouteArraySize(); ++i)
798  sourceRoute.push_back(apiMsg->getSourceRoute(i));
799 
800  route(apiMsg->getDestKey(), static_cast<CompType>(apiMsg->getDestComp()),
801  static_cast<CompType>(apiMsg->getSrcComp()), apiMsg->decapsulate(),
802  sourceRoute);
803  } else if (dynamic_cast<KBRforward*>(msg) != NULL) {
804  KBRforward* apiMsg = static_cast<KBRforward*>(msg);
805  OverlayCtrlInfo* overlayCtrlInfo =
806  check_and_cast<OverlayCtrlInfo*>
807  (msg->removeControlInfo());
808 
809  BaseAppDataMessage* dataMsg =
810  new BaseAppDataMessage();
811  dataMsg->setType(APPDATA);
812  dataMsg->setBitLength(BASEAPPDATA_L(dataMsg));
813  dataMsg->setName(apiMsg->getEncapsulatedPacket()->getName());
814  dataMsg->encapsulate(apiMsg->decapsulate());
815  dataMsg->setSrcComp(overlayCtrlInfo->getSrcComp());
816  dataMsg->setDestComp(overlayCtrlInfo->getDestComp());
817  dataMsg->setStatType(APP_DATA_STAT);
818 
819  BaseRouteMessage* routeMsg = new BaseRouteMessage(dataMsg->getName());
820  routeMsg->setType(OVERLAYROUTE);
821  routeMsg->setBitLength(BASEROUTE_L(routeMsg));
822  routeMsg->encapsulate(dataMsg);
823 
824  routeMsg->setStatType(APP_DATA_STAT);
825  routeMsg->setRoutingType(overlayCtrlInfo->getRoutingType());
826  routeMsg->setDestKey(apiMsg->getDestKey());
827  routeMsg->setSrcNode(overlayCtrlInfo->getSrcNode());
828  routeMsg->setHopCount(overlayCtrlInfo->getHopCount());
829  routeMsg->setControlInfo(overlayCtrlInfo);
830 
831  // message marked with this-pointer as already forwarded to tier1
832  routeMsg->setContextPointer(this);
833 
834  std::vector<TransportAddress> sourceRoute;
835  sourceRoute.push_back(apiMsg->getNextHopNode());
836  sendToKey(apiMsg->getDestKey(), routeMsg, 1, sourceRoute);
837  }
838 
839  delete msg;
840  }
841 
842  // process other messages from App
843  else if (msg->getArrivalGate() == appGate) {
844  handleAppMessage(msg);
845  } else if(msg->arrivedOn("tcpIn")) {
846  handleTCPMessage(msg);
847  } else if (dynamic_cast<CompReadyMessage*>(msg)) {
848  CompReadyMessage* readyMsg = static_cast<CompReadyMessage*>(msg);
849  if (((bool)par("joinOnApplicationRequest") == false) &&
850  readyMsg->getReady() &&
851  readyMsg->getComp() == NEIGHBORCACHE_COMP) {
852  cObject** context = globalNodeList->getContext(getThisNode());
853  if (restoreContext && context && *context) {
854  BaseOverlayContext* overlayContext = static_cast<BaseOverlayContext*>(*context);
855  globalNodeList->setMalicious(getThisNode(),
856  overlayContext->malicious);
857  join(overlayContext->key);
858  } else if (!readyMsg->getNodeId().isUnspecified()) {
859  //std::cout << "readymsg at BO" << std::endl;
860  join(readyMsg->getNodeId());
861  } else {
862  join();
863  }
864  } /*else if (!readyMsg->getReady() &&
865  readyMsg->getComp() == NEIGHBORCACHE_COMP) {
866  //STATE =
867  setOverlayReady(false);
868  } */
869  delete msg;
870  } else {
871  throw cRuntimeError("BaseOverlay::handleMessage(): Received msg with "
872  "unknown type!");
873  delete msg;
874  }
875 }
876 
878  const OverlayKey& destKey)
879 {
880  switch (msg->getType()) {
881  case OVERLAYSIGNALING:
882  handleUDPMessage(msg);
883  return;
884 
885  case RPC: {
886  // process rpc-messages
887  BaseRpcMessage* rpcMsg = check_and_cast<BaseRpcMessage*>(msg);
888 
889  // TODO destKey -> overlayCtrlInfo
890  internalHandleRpcMessage(rpcMsg);
891  return;
892  }
893 
894  case APPDATA: {
895  //TODO use route messages? here: set transport type to ROUTE for "naked"
896  // app messages
897  OverlayCtrlInfo* overlayCtrlInfo = check_and_cast<OverlayCtrlInfo*>(msg->getControlInfo());
898  overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
899 
900  BaseAppDataMessage* baseAppDataMsg =
901  check_and_cast<BaseAppDataMessage*>(msg);
902  callDeliver(baseAppDataMsg, destKey);
903  return;
904  }
905 
906  case OVERLAYROUTE: {
907  BaseRouteMessage* baseRouteMsg =
908  check_and_cast<BaseRouteMessage*>(msg);
909 
910  // collect delay-value of completed hop
911  if (collectPerHopDelay) {
912  baseRouteMsg->setHopDelayArraySize(baseRouteMsg->
913  getHopDelayArraySize() + 1);
914  baseRouteMsg->setHopDelay(baseRouteMsg->getHopDelayArraySize() - 1,
915  simTime() - baseRouteMsg->getHopStamp());
916  }
917 
918  OverlayCtrlInfo* overlayCtrlInfo
919  = check_and_cast<OverlayCtrlInfo*>(baseRouteMsg
920  ->removeControlInfo());
921  // set transport type
922  overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
923 
924  // source routing: save visited nodes, copy next hops
925  std::vector<TransportAddress> sourceRoute;
926  if ((baseRouteMsg->getNextHopsArraySize() > 0) ||
927  (baseRouteMsg->getRoutingType() == RECURSIVE_SOURCE_ROUTING) ||
928  recordRoute) {
929  // store the TransportAddress of the sender in the visited list
930  baseRouteMsg->setVisitedHopsArraySize(baseRouteMsg
931  ->getVisitedHopsArraySize() + 1);
932  baseRouteMsg->setVisitedHops(baseRouteMsg
933  ->getVisitedHopsArraySize() - 1,
934  overlayCtrlInfo->getLastHop());
935 
936  // remove nodes from next hops and copy them to sourceRoute
937  if (baseRouteMsg->getNextHopsArraySize() > 0) {
938  sourceRoute.resize(baseRouteMsg->getNextHopsArraySize()- 1);
939  for (uint32_t i = 1; i < baseRouteMsg->getNextHopsArraySize();
940  ++i) {
941  sourceRoute[i - 1] = baseRouteMsg->getNextHops(i);
942  }
943  baseRouteMsg->setNextHopsArraySize(0);
944  }
945  }
946 
947  overlayCtrlInfo->setSrcNode(baseRouteMsg->getSrcNode());
948 
949  // decapsulate msg if node is sibling for destKey
950  // or message is at its destination node
951  bool err;
952  if ((sourceRoute.size() == 0) &&
953  (baseRouteMsg->getDestKey().isUnspecified() ||
954  isSiblingFor(thisNode, baseRouteMsg->getDestKey(), 1, &err)
955  /*&& !err*/)) {
956  overlayCtrlInfo->setHopCount(baseRouteMsg->getHopCount());
957  overlayCtrlInfo->setRoutingType(baseRouteMsg->getRoutingType());
958 
959  if (baseRouteMsg->getVisitedHopsArraySize() > 0) {
960  // recorded route available => add to srcNode
961  NodeHandle srcRoute(baseRouteMsg->getSrcNode().getKey(),
962  baseRouteMsg->getVisitedHops(0));
963 
964  for (uint32_t i = 0; i < baseRouteMsg->getVisitedHopsArraySize(); ++i) {
965  srcRoute.appendSourceRoute(baseRouteMsg->getVisitedHops(i));
966  }
967 
968  overlayCtrlInfo->setSrcRoute(srcRoute);
969  } else if (baseRouteMsg->getDestKey().isUnspecified()) {
970  // directly received (neither key routed nor source routed)
971  // TODO: does this happen for a BaseRouteMessage?
972  overlayCtrlInfo->setSrcRoute(
973  NodeHandle(baseRouteMsg->getSrcNode().getKey(),
974  overlayCtrlInfo->getLastHop()));
975  } else {
976  // route to key and no recorded route available
977  overlayCtrlInfo->setSrcRoute(baseRouteMsg->getSrcNode());
978  }
979 
980  // copy visited nodes to control info
981  overlayCtrlInfo->setVisitedHopsArraySize(
982  baseRouteMsg->getVisitedHopsArraySize());
983 
984  for (uint32_t i = 0; i < baseRouteMsg->getVisitedHopsArraySize();
985  ++i) {
986  overlayCtrlInfo->setVisitedHops(i,
987  baseRouteMsg->getVisitedHops(i));
988  }
989 
990  BaseOverlayMessage* tmpMsg
991  = check_and_cast<BaseOverlayMessage*>(baseRouteMsg
992  ->decapsulate());
993  tmpMsg->setControlInfo(overlayCtrlInfo);
994 
995  // delay between hops
996  if (collectPerHopDelay) {
997  RECORD_STATS(
998  size_t i;
999  for (i = singleHopDelays.size();
1000  i < baseRouteMsg->getHopDelayArraySize();) {
1001  singleHopDelays.push_back(new HopDelayRecord[++i]);
1002  }
1003 
1004  i = baseRouteMsg->getHopDelayArraySize() - 1;
1005  HopDelayRecord* hdr = singleHopDelays[i];
1006 
1007  for (size_t j = 0; j <= i; ++j) {
1008  hdr[j].count++;
1009  hdr[j].val += baseRouteMsg->getHopDelay(j);
1010  }
1011  );
1012  }
1013 
1014  // handle encapsulated message at destination node
1015  if (((baseRouteMsg->getRoutingType() == ITERATIVE_ROUTING)
1016  || (baseRouteMsg->getRoutingType() == EXHAUSTIVE_ITERATIVE_ROUTING)
1017  )
1018  || recursiveRoutingHook(thisNode, baseRouteMsg)) {
1019  handleBaseOverlayMessage(tmpMsg, baseRouteMsg->getDestKey());
1020  delete baseRouteMsg;
1021  }
1022  return;
1023  } else {
1024  // forward msg if this node is not responsible for the key
1025  baseRouteMsg->setControlInfo(overlayCtrlInfo);
1026 
1027  // if this node is malicious drop the message
1028  if (isMalicious() && dropRouteMessageAttack) {
1029  EV << "[BaseOverlay::handleBaseOverlayMessage() @ " << thisNode.getIp()
1030  << " (" << thisNode.getKey().toString(16) << ")]\n"
1031  << " BaseRouteMessage gets dropped because this node is malicious"
1032  << endl;
1033  //std::cout << "malicious!" << std::endl;
1034  RECORD_STATS(numDropped++;
1035  bytesDropped += baseRouteMsg->getByteLength());
1036  delete baseRouteMsg;
1037  return;
1038  }
1039 
1040  sendToKey(baseRouteMsg->getDestKey(), baseRouteMsg, 1, sourceRoute);
1041  return;
1042  }
1043  break;
1044  }
1045 
1046  default:
1047  EV << "[BaseOverlay::handleBaseOverlayMessage() @ " << thisNode.getIp()
1048  << " (" << thisNode.getKey().toString(16) << ")]\n"
1049  << " Received unknown message from UDP of type " << msg->getName()
1050  << endl;
1051  break;
1052  }
1053 }
1054 
1055 void BaseOverlay::receiveChangeNotification(int category, const cPolymorphic * details)
1056 {
1057  Enter_Method_Silent();
1058  if (category == NF_OVERLAY_TRANSPORTADDRESS_CHANGED) {
1059  handleTransportAddressChangedNotification();
1060  } else if (category == NF_OVERLAY_NODE_LEAVE) {
1061  handleNodeLeaveNotification();
1062  } else if (category == NF_OVERLAY_NODE_GRACEFUL_LEAVE) {
1063  handleNodeGracefulLeaveNotification();
1064  }
1065 }
1066 
1068 {
1069  // get new ip address
1070  thisNode.setIp(IPAddressResolver().addressOf(
1071  getParentModule()->getParentModule()));
1072 
1073  joinOverlay();
1074 }
1075 
1077 {
1078  // ...
1079 }
1080 
1082 {
1083  // ...
1084 }
1085 
1086 //virtual protected
1088 {
1089  delete msg;
1090 }
1091 
1093 {
1094  delete msg;
1095 }
1096 
1097 //virtual protected
1099 {
1100  // collect statistics ...
1101 }
1102 
1104 {
1105  //TODO new setOverlayState(State state) function
1106  if ((ready && internalReadyState) || (!ready && !internalReadyState)) {
1107  return;
1108  }
1109 
1110  internalReadyState = ready;
1111 
1112  getDisplayString().setTagArg("i", 1, ready ? "" : "red");
1113  if (isMalicious()) {
1114  getDisplayString().setTagArg("i", 1, ready ? "green" : "yellow");
1115  }
1116 
1117  globalNodeList->setOverlayReadyIcon(getThisNode(), ready);
1118 
1119  if (ready) {
1120  bootstrapList->registerBootstrapNode(thisNode, overlayId);
1121  } else {
1122  bootstrapList->removeBootstrapNode(thisNode, overlayId);
1123  }
1124 
1125  if (globalParameters->getPrintStateToStdOut()) {
1126  std::cout << "OVERLAY STATE: " << (ready ? "READY (" : "OFFLINE (")
1127  << thisNode << ")" << std::endl;
1128  }
1129 
1131  msg->setReady(ready);
1132  msg->setComp(OVERLAY_COMP);
1133 
1134  // notify all registered components about new overlay state
1135  sendMessageToAllComp(msg, OVERLAY_COMP);
1136 }
1137 
1138 
1139 
1140 //------------------------------------------------------------------------
1141 //--- Messages -----------------------------------------------------------
1142 //------------------------------------------------------------------------
1143 
1145  BaseRouteMessage* msg,
1146  bool ack)
1147 {
1148  OverlayCtrlInfo* ctrlInfo =
1149  dynamic_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
1150 
1151  // records statistics, if we forward this message
1152  if (ctrlInfo && ctrlInfo->getLastHop().getIp() != thisNode.getIp()) {
1153  if (msg->getStatType() == APP_DATA_STAT) {
1154  RECORD_STATS(numAppDataForwarded++;
1155  bytesAppDataForwarded += msg->getByteLength());
1156  } else if (msg->getStatType() == APP_LOOKUP_STAT){
1157  RECORD_STATS(numAppLookupForwarded++;
1158  bytesAppLookupForwarded += msg->getByteLength());
1159  } else {
1160  RECORD_STATS(numMaintenanceForwarded++;
1161  bytesMaintenanceForwarded += msg->getByteLength());
1162  }
1163  }
1164 
1165  delete ctrlInfo;
1166 
1167  if (msg && (dest != thisNode)) {
1168  msg->setHopCount(msg->getHopCount() + 1);
1169  }
1170  if (!ack)
1171  sendMessageToUDP(dest, msg);
1172  else {
1173  NextHopCall* nextHopCall = new NextHopCall(msg->getName());
1174  nextHopCall->setBitLength(NEXTHOPCALL_L(nextHopCall));
1175  nextHopCall->encapsulate(msg);
1176  nextHopCall->setStatType(msg->getStatType());
1177 
1178  // TODO parameter, in recursive mode routeRetries should be 0,
1179  // in iterative mode routeRetries could be more than 0
1180  uint8_t routeRetries = 0;
1181  sendUdpRpcCall(dest, nextHopCall, NULL, -1, routeRetries);
1182  }
1183 }
1184 
1185 
1187  cPacket* msg, simtime_t delay)
1188 {
1189  // if there's still a control info attached to the message, remove it
1190  cPolymorphic* ctrlInfo = msg->removeControlInfo();
1191  if (ctrlInfo != NULL)
1192  delete ctrlInfo;
1193 
1194  // debug message
1195  if (debugOutput) {
1196  EV << "[BaseOverlay::sendMessageToUDP() @ " << thisNode.getIp()
1197  << " (" << thisNode.getKey().toString(16) << ")]\n"
1198  << " Sending " << *msg << " to " << dest.getIp()
1199  << endl;
1200  }
1201 
1202  msg->setKind(UDP_C_DATA);
1203  UDPControlInfo* udpControlInfo = new UDPControlInfo();
1204  udpControlInfo->setSrcAddr(thisNode.getIp());
1205  udpControlInfo->setSrcPort(thisNode.getPort());
1206  udpControlInfo->setDestAddr(dest.getIp());
1207  udpControlInfo->setDestPort(dest.getPort());
1208  msg->setControlInfo(udpControlInfo);
1209 
1210  if (dest != thisNode) {
1211  BaseOverlayMessage* baseOverlayMsg
1212  = check_and_cast<BaseOverlayMessage*>(msg);
1213  // record statistics, if message is not local
1214  if (baseOverlayMsg->getStatType() == APP_DATA_STAT) {
1215  RECORD_STATS(numAppDataSent++;
1216  bytesAppDataSent += msg->getByteLength());
1217  } else if (baseOverlayMsg->getStatType() == APP_LOOKUP_STAT){
1218  RECORD_STATS(numAppLookupSent++; bytesAppLookupSent +=
1219  msg->getByteLength());
1220  } else { // MAINTENANCE_STAT
1221  RECORD_STATS(numMaintenanceSent++; bytesMaintenanceSent +=
1222  msg->getByteLength());
1223  }
1224  recordOverlaySentStats(baseOverlayMsg);
1225 
1226  if (dynamic_cast<BaseResponseMessage*>(msg) && getMeasureAuthBlock()) {
1227  // TODO: Also consider signed DhtPutMessages
1228  RECORD_STATS(bytesAuthBlockSent += ceil(AUTHBLOCK_L/8.0));
1229  }
1230  } else {
1231  if (dest.getIp() == thisNode.getIp()) { // to same node, but different port
1232  RECORD_STATS(numInternalSent++; bytesInternalSent += msg->getByteLength());
1233  }
1234  }
1235  sendDelayed(msg, delay, "udpOut");
1236 }
1237 
1238 //------------------------------------------------------------------------
1239 //--- Basic Routing ------------------------------------------------------
1240 //------------------------------------------------------------------------
1241 
1242 static int pendingLookups = 0;
1243 
1245 {
1246  lookups = LookupSet();
1247 }
1248 
1250 {
1251  while (lookups.size() > 0) {
1252  (*lookups.begin())->abortLookup();
1253  }
1254  lookups.clear();
1255 }
1256 
1258 {
1259 private:
1263 public:
1265  this->overlay = overlay;
1266  this->msg = msg;
1267  globalStatistics = overlay->globalStatistics;
1268  pendingLookups++;
1269  }
1270 
1272  pendingLookups--;
1273  overlay = NULL;
1274  if (msg != NULL) {
1275  delete msg;
1276  msg = NULL;
1277  }
1278  }
1279 
1280  virtual void lookupFinished(AbstractLookup *lookup) {
1281  if (dynamic_cast<BaseRouteMessage*>(msg)) {
1282  BaseRouteMessage* routeMsg = static_cast<BaseRouteMessage*>(msg);
1283  if (lookup->isValid()) {
1284  if (lookup->getResult().size()==0) {
1285  EV << "[SendToKeyListener::lookupFinished()]\n"
1286  " [ERROR] SendToKeyListener: Valid result, "
1287  "but empty array." << endl;
1288  } else {
1289  routeMsg->setHopCount(routeMsg->getHopCount()
1290  + lookup->getAccumulatedHops());
1291 
1292  for (uint32_t i=0; i<lookup->getResult().size(); i++) {
1293  overlay->sendRouteMessage(lookup->getResult()[i],
1294  static_cast<BaseRouteMessage*>
1295  (routeMsg->dup()),
1296  overlay->routeMsgAcks);
1297  }
1298  }
1299  } else {
1300  EV << "[SendToKeyListener::lookupFinished()]\n"
1301  << " Lookup failed - dropping message"
1302  << endl;
1303 
1304  /*
1305  std::cout << simTime() << " "
1306  << routeMsg->getEncapsulatedPacket()->getName() << " "
1307  << routeMsg->getSrcNode()
1308  << " [SendToKeyListener::lookupFinished()]\n"
1309  << " Lookup failed - dropping message"
1310  << std::endl;
1311  */
1312 
1313  RECORD_STATS(overlay->numDropped++;
1314  overlay->bytesDropped += routeMsg->getByteLength());
1315  }
1316  } else if (dynamic_cast<LookupCall*>(msg)) {
1317  LookupCall* call = static_cast<LookupCall*>(msg);
1318  LookupResponse* response = new LookupResponse();
1319  response->setKey(call->getKey());
1320  response->setHopCount(lookup->getAccumulatedHops());
1321  if (lookup->isValid()) {
1322  response->setIsValid(true);
1323  response->setSiblingsArraySize(lookup->getResult().size());
1324  for (uint32_t i=0; i<lookup->getResult().size(); i++) {
1325  response->setSiblings(i, lookup->getResult()[i]);
1326  }
1327  if (lookup->getResult().size() == 0) {
1328  EV << "[SendToKeyListener::lookupFinished() @ "
1329  << overlay->thisNode.getIp()
1330  << " (" << overlay->thisNode.getKey().toString(16) << ")]\n"
1331  << " LookupCall "
1332  << call->getNonce()
1333  << " failed! (size=0)" << endl;
1334  }
1335  } else {
1336  response->setIsValid(false);
1337  EV << "[SendToKeyListener::lookupFinished() @ "
1338  << overlay->thisNode.getIp()
1339  << " (" << overlay->thisNode.getKey().toString(16) << ")]\n"
1340  << " LookupCall "
1341  << call->getNonce()
1342  << " failed!" << endl;
1343  }
1344  overlay->sendRpcResponse(call, response);
1345  msg = NULL;
1346  } else {
1347  throw cRuntimeError("SendToKeyListener::lookupFinished(): "
1348  "Unknown message type!");
1349  }
1350  delete this;
1351  }
1352 };
1353 
1354 void BaseOverlay::route(const OverlayKey& key, CompType destComp,
1355  CompType srcComp, cPacket* msg,
1356  const std::vector<TransportAddress>& sourceRoute,
1357  RoutingType routingType)
1358 {
1359  if (key.isUnspecified() &&
1360  (!sourceRoute.size() || sourceRoute[0].isUnspecified()))
1361  throw cRuntimeError("route(): Key and hint unspecified!");
1362 
1363  // encapsulate in a app data message for multiplexing
1364  // to destination component
1365  BaseAppDataMessage* baseAppDataMsg =
1366  new BaseAppDataMessage("BaseAppDataMessage");
1367  baseAppDataMsg->setType(APPDATA);
1368  baseAppDataMsg->setDestComp(destComp);
1369  baseAppDataMsg->setSrcComp(srcComp);
1370  baseAppDataMsg->setBitLength(BASEAPPDATA_L(baseAppDataMsg));
1371  baseAppDataMsg->setName(msg->getName());
1372 
1373  baseAppDataMsg->setStatType(APP_DATA_STAT);
1374  baseAppDataMsg->encapsulate(msg);
1375 
1376  // debug output
1377  if (debugOutput) {
1378  EV << "[BaseOverlay::route() @ " << thisNode.getIp()
1379  << " (" << thisNode.getKey().toString(16) << ")]\n"
1380  << " Received message from application"
1381  << endl;
1382  }
1383 
1384  if (key.isUnspecified() && sourceRoute.size() <= 1) {
1385  sendMessageToUDP(sourceRoute[0], baseAppDataMsg);
1386  } else {
1387  if (internalReadyState == false) {
1388  // overlay not ready => sendToKey doesn't work yet
1389  EV << "[BaseOverlay::route() @ "
1390  << getThisNode().getIp()
1391  << " (" << getThisNode().getKey().toString(16) << ")]\n"
1392  << " Couldn't route application message to key "
1393  << key.toString(16)
1394  << " because the overlay module is not ready!" << endl;
1395  RECORD_STATS(numDropped++;
1396  bytesDropped += baseAppDataMsg->getByteLength());
1397  delete baseAppDataMsg;
1398  return;
1399  }
1400 
1401  sendToKey(key, baseAppDataMsg, 1, sourceRoute, routingType);
1402  }
1403 }
1404 
1406  BaseRouteMessage* msg)
1407 {
1408  return true;
1409 }
1410 
1412  int numSiblings,
1413  const std::vector<TransportAddress>& sourceRoute,
1414  RoutingType routingType)
1415 {
1416  BaseRouteMessage* routeMsg = NULL;
1417 
1418  if (routingType == DEFAULT_ROUTING) routingType = defaultRoutingType;
1419 
1420  if (debugOutput) {
1421  EV << "[BaseOverlay::sendToKey() @ " << thisNode.getIp()
1422  << " (" << thisNode.getKey().toString(16) << ")]\n"
1423  << " Sending " << msg << " to " << key
1424  << endl;
1425  }
1426 
1427  if (key.isUnspecified() &&
1428  !(sourceRoute.size() && !sourceRoute[0].isUnspecified()))
1429  throw cRuntimeError("BaseOverlay::sendToKey(): "
1430  "unspecified destination address and key!");
1431 
1432  if (msg->getType() != OVERLAYROUTE) {
1433  assert(!msg->getControlInfo());
1434  routeMsg = new BaseRouteMessage("BaseRouteMessage");
1435  routeMsg->setType(OVERLAYROUTE);
1436  routeMsg->setRoutingType(routingType);
1437  routeMsg->setDestKey(key);
1438  routeMsg->setSrcNode(thisNode);
1439  routeMsg->setStatType(msg->getStatType());
1440  // copy the name of the inner message
1441  routeMsg->setName(msg->getName());
1442  routeMsg->setBitLength(BASEROUTE_L(routeMsg));
1443  routeMsg->encapsulate(msg);
1444 
1445  OverlayCtrlInfo* routeCtrlInfo = new OverlayCtrlInfo;
1446  routeCtrlInfo->setLastHop(thisNode);
1447  routeCtrlInfo->setTransportType(ROUTE_TRANSPORT);
1448  routeCtrlInfo->setRoutingType(routingType);
1449  routeMsg->setControlInfo(routeCtrlInfo);
1450 
1451  //message marked as not already forwarded to tier1
1452  routeMsg->setContextPointer(NULL);
1453  } else {
1454  routeMsg = check_and_cast<BaseRouteMessage*>(msg);
1455  routingType = static_cast<RoutingType>(routeMsg->getRoutingType());
1456  }
1457 
1458  // set timestamp for next hop
1459  if (collectPerHopDelay) {
1460  routeMsg->setHopStamp(simTime());
1461  }
1462 
1463  if (sourceRoute.size() && !sourceRoute[0].isUnspecified()) {
1464  // send msg to nextHop if specified (used for e.g. join rpcs)
1465  OverlayCtrlInfo* ctrlInfo = check_and_cast<OverlayCtrlInfo*>
1466  (routeMsg->getControlInfo());
1467  ctrlInfo->setTransportType(UDP_TRANSPORT);
1468  assert(routeMsg->getNextHopsArraySize() == 0);
1469  routeMsg->setNextHopsArraySize(sourceRoute.size());
1470  for (uint32_t i = 0; i < sourceRoute.size(); ++i)
1471  routeMsg->setNextHops(i, sourceRoute[i]);
1472  if (recursiveRoutingHook(sourceRoute[0], routeMsg)) { //test
1473  sendRouteMessage(sourceRoute[0], routeMsg, routeMsgAcks);
1474  }
1475  return;
1476  }
1477 
1478  if ((routingType == ITERATIVE_ROUTING)
1479  || (routingType == EXHAUSTIVE_ITERATIVE_ROUTING)
1480  ) {
1481 
1482  // create lookup and sent to key
1483  AbstractLookup* lookup = createLookup(routingType, routeMsg, NULL,
1484  (routeMsg->getStatType() == APP_DATA_STAT));
1485  lookup->lookup(routeMsg->getDestKey(), numSiblings, hopCountMax,
1486  0, new SendToKeyListener(this, routeMsg));
1487  } else {
1488  // recursive routing
1489  NodeVector* nextHops = findNode(routeMsg->getDestKey(),
1490  recNumRedundantNodes,
1491  numSiblings, routeMsg);
1492 
1493  if (nextHops->size() == 0) {
1494  EV << "[BaseOverlay::sendToKey() @ " << thisNode.getIp()
1495  << " (" << thisNode.getKey().toString(16) << ")]\n"
1496  << " FindNode() returned NULL - dropping message"
1497  << endl;
1498  //std::cout << simTime() << " " << thisNode.getIp() << " " << state
1499  // << " FindNode() returned NULL - dropping message "
1500  // << routeMsg->getName() << " from "
1501  // << routeMsg->getSrcNode() << std::endl;
1502 
1503  // statistics
1504  RECORD_STATS(numDropped++; bytesDropped += routeMsg->getByteLength());
1505  delete routeMsg;
1506  } else {
1507  // delete message if the hop count maximum is exceeded
1508  if (routeMsg->getHopCount() >= hopCountMax) {
1509 
1510  EV << "[BaseOverlay::sendToKey() @ " << thisNode.getIp()
1511  << " (" << thisNode.getKey().toString(16) << ")]\n"
1512  << " Discards " << routeMsg->getName() << " from "
1513  << routeMsg->getSrcNode().getIp() << "\n"
1514  << " The hop count maximum has been exceeded ("
1515  << routeMsg->getHopCount() << ">="
1516  << hopCountMax << ")"
1517  << endl;
1518  //std::cout << "[BaseOverlay::sendToKey() @ " << thisNode.getIp()
1519  // << " (" << thisNode.getKey().toString(16) << ")]\n"
1520  // << " Discards " << routeMsg->getName() << " from "
1521  // << routeMsg->getSrcNode().getIp() << "\n"
1522  // << " The hop count maximum has been exceeded ("
1523  // << routeMsg->getHopCount() << ">="
1524  // << hopCountMax << ")"
1525  // << std::endl;
1526 
1527  // statistics
1528  RECORD_STATS(numDropped++;
1529  bytesDropped += routeMsg->getByteLength());
1530  delete routeMsg;
1531  delete nextHops;
1532  return;
1533  }
1534 
1535  OverlayCtrlInfo* overlayCtrlInfo =
1536  dynamic_cast<OverlayCtrlInfo*>(routeMsg->getControlInfo());
1537  assert(overlayCtrlInfo);
1538 
1539  // check and choose nextHop candidate
1540  NodeHandle* nextHop = NULL;
1541  bool err, isSibling;
1542  isSibling = isSiblingFor(thisNode, routeMsg->getDestKey(),
1543  numSiblings, &err);
1544 
1545  // if route is recorded we can do a real loop detection
1546  std::set<TransportAddress> visitedHops;
1547  for (uint32_t i = 0; i < routeMsg->getVisitedHopsArraySize(); ++i) {
1548  visitedHops.insert(routeMsg->getVisitedHops(i));
1549  }
1550 
1551  for (uint32_t index = 0; nextHop == NULL && nextHops->size() > index;
1552  ++index) {
1553  nextHop = &((*nextHops)[index]);
1554  // loop detection
1555  if (((overlayCtrlInfo->getLastHop() == *nextHop) &&
1556  (*nextHop != thisNode)) ||
1557  (visitedHops.find(*nextHop) != visitedHops.end()) ||
1558  // do not forward msg to source node
1559  ((*nextHop == routeMsg->getSrcNode()) &&
1560  (thisNode != routeMsg->getSrcNode())) ||
1561  // nextHop is thisNode, but isSiblingFor() is false
1562  ((*nextHop == thisNode) && (!isSibling))) {
1563  nextHop = NULL;
1564  }
1565  }
1566 
1567  if (nextHop == NULL) {
1568  if (!checkFindNode(routeMsg)) {
1569  EV << "[BaseOverlay::sendToKey() @ " << thisNode.getIp()
1570  << " (" << thisNode.getKey().toString(16) << ")]\n"
1571  << " Discards " << routeMsg->getName() << " from "
1572  << routeMsg->getSrcNode().getIp() << "\n"
1573  << " No useful nextHop found!"
1574  << endl;
1575  //std::cout << thisNode.getIp() << " packet from "
1576  // << routeMsg->getSrcNode().getIp()
1577  // << " dropped: " << routeMsg
1578  // << " " << state << std::endl;
1579  RECORD_STATS(numDropped++;
1580  bytesDropped += routeMsg->getByteLength());
1581  }
1582  delete routeMsg;
1583  delete nextHops;
1584  return;
1585  }
1586 
1587  assert(!nextHop->isUnspecified());
1588 
1589  // callForward to app
1590  if (useCommonAPIforward &&
1591  dynamic_cast<BaseAppDataMessage*>(
1592  routeMsg->getEncapsulatedPacket()) &&
1593  routeMsg->getContextPointer() == NULL) {
1594  callForward(routeMsg->getDestKey(), routeMsg, *nextHop);
1595  delete nextHops;
1596  return;
1597  }
1598  //message marked as not already forwarded
1599  routeMsg->setContextPointer(NULL);
1600 
1601  // is this node responsible?
1602  if (*nextHop == thisNode) {
1603  if (isSibling && !err) {
1604  //EV << "[BaseOverlay::sendToKey() @ " << thisNode.getIp()
1605  // << " (" << thisNode.getKey().toString(16) << ")]\n"
1606  // << " Forwards msg for key " << routeMsg->getDestKey() "\n"
1607  // << " to node " << (*nextHops)[0]
1608  // << endl;
1609  delete nextHops;
1610  assert(routeMsg->getControlInfo());
1611  handleBaseOverlayMessage(routeMsg, key);
1612  return;
1613  } else {
1614  throw cRuntimeError("isSiblingsFor() is true with an "
1615  "error: Erroneous method "
1616  "isSiblingFor()!");
1617  }
1618  }
1619  // else forward msg if this node is not responsible for the key
1620  overlayCtrlInfo->setHopCount(routeMsg->getHopCount());
1621  if (recursiveRoutingHook(*nextHop, routeMsg)) {
1622  sendRouteMessage(*nextHop, routeMsg, routeMsgAcks);
1623  }
1624  }
1625  delete nextHops;
1626  }
1627 }
1628 
1630 {
1631  if (dynamic_cast<FindNodeCall*>(routeMsg->getEncapsulatedPacket())) {
1632  FindNodeCall* findNodeCall =
1633  static_cast<FindNodeCall*>(routeMsg->decapsulate());
1634  findNodeCall
1635  ->setControlInfo(check_and_cast<OverlayCtrlInfo*>
1636  (routeMsg->removeControlInfo()));
1637  if (findNodeCall->getSrcNode() != thisNode) {
1638  findNodeRpc(findNodeCall);
1639  return true;
1640  } //else std::cout << " autsch!! " << std::endl;
1641  }
1642  return false;
1643 }
1644 
1645 //protected: create a lookup class
1647  const BaseOverlayMessage* msg,
1648  const cPacket* findNodeExt,
1649  bool appLookup)
1650 {
1651  AbstractLookup* newLookup;
1652 
1653  if (routingType == DEFAULT_ROUTING) {
1654  routingType = defaultRoutingType;
1655  }
1656 
1657  switch (routingType) {
1658  case ITERATIVE_ROUTING:
1660  newLookup = new IterativeLookup(this, routingType,
1661  iterativeLookupConfig, findNodeExt,
1662  appLookup);
1663  break;
1667  newLookup = new RecursiveLookup(this, routingType,
1668  recursiveLookupConfig,
1669  appLookup);
1670  break;
1671  default:
1672  throw cRuntimeError("BaseOverlay::createLookup():"
1673  " Unknown routingType!");
1674  break;
1675  }
1676 
1677  lookups.insert(newLookup);
1678  return newLookup;
1679 }
1680 
1682 {
1683  lookups.erase(lookup);
1684 }
1685 
1686 //virtual public
1688  const OverlayKey& y,
1689  bool useAlternative) const
1690 {
1691  throw cRuntimeError("BaseOverlay::distance(): Not implemented!");
1693 }
1694 
1695 //protected: find closest nodes
1697  int numRedundantNodes,
1698  int numSiblings,
1699  BaseOverlayMessage* msg)
1700 {
1701  throw cRuntimeError("findNode: Not implemented!");
1702  return NULL;
1703 }
1704 
1705 //protected: join the overlay with a given nodeID
1707 {
1708 // std::cout << "BaseOverlay::joinOverlay(): Not implemented!" << endl;
1709  return;
1710 }
1711 
1713 {
1714  //std::cout << "Mooooo" << std::endl;
1715  return true;
1716 }
1717 
1718 //------------------------------------------------------------------------
1719 //--- RPCs ---------------------------------------------------------------
1720 //------------------------------------------------------------------------
1721 
1722 //private
1724 {
1725  // call rpc stubs
1726  RPC_SWITCH_START( msg );
1727  RPC_DELEGATE( FindNode, findNodeRpc );
1728  RPC_DELEGATE( FailedNode, failedNodeRpc );
1729  RPC_DELEGATE( Lookup, lookupRpc );
1730  RPC_DELEGATE( NextHop, nextHopRpc );
1731  RPC_SWITCH_END( );
1732 
1733  // if RPC was handled return true, else tell the parent class to handle it
1735 }
1736 
1738  cPolymorphic* context,
1739  int rpcId, simtime_t rtt)
1740 {
1741  BaseRpc::internalHandleRpcResponse(msg, context, rpcId, rtt);
1742 }
1743 
1745  const TransportAddress& dest,
1746  cPolymorphic* context, int rpcId,
1747  const OverlayKey& destKey)
1748 {
1749  RPC_SWITCH_START( msg )
1750  RPC_ON_CALL( NextHop )
1751  {
1752  BaseRouteMessage* tempMsg
1753  = check_and_cast<BaseRouteMessage*>(msg->decapsulate());
1754 
1755  assert(!tempMsg->getControlInfo());
1756  if (!tempMsg->getControlInfo()) {
1757  OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo;
1758  overlayCtrlInfo->setLastHop(thisNode);
1759  overlayCtrlInfo->setHopCount(tempMsg->getHopCount());
1760  overlayCtrlInfo->setSrcNode(tempMsg->getSrcNode());
1761  overlayCtrlInfo->setRoutingType(tempMsg->getRoutingType());
1762  overlayCtrlInfo->setTransportType(UDP_TRANSPORT);
1763  tempMsg->setControlInfo(overlayCtrlInfo);
1764  }
1765  // remove node from local routing tables
1766  // + route message again if possible
1767  assert(!dest.isUnspecified() && destKey.isUnspecified());
1768  if (handleFailedNode(dest)) {
1769  if (!tempMsg->getDestKey().isUnspecified() &&
1770  tempMsg->getRoutingType() != ITERATIVE_ROUTING &&
1772  // TODO: msg is resent only in recursive mode
1773  EV << "[BaseOverlay::internalHandleRpcTimeout() @ "
1774  << thisNode.getIp()
1775  << " (" << thisNode.getKey().toString(16) << ")]\n"
1776  << " Resend msg for key " << destKey
1777  << endl;
1778  handleBaseOverlayMessage(tempMsg, destKey);
1779  } else if(tempMsg->getNextHopsArraySize() > 1) {
1780  for (uint8_t i = 0; i < tempMsg->getNextHopsArraySize() - 1; ++i) {
1781  tempMsg->setNextHops(i, tempMsg->getNextHops(i + 1));
1782  }
1783  tempMsg->setNextHopsArraySize(tempMsg->getNextHopsArraySize() - 1);
1784  EV << "[BaseOverlay::internalHandleRpcTimeout() @ "
1785  << thisNode.getIp()
1786  << " (" << thisNode.getKey().toString(16) << ")]\n"
1787  << " Resend msg to next available node in nextHops[]: "
1788  << tempMsg->getNextHops(0).getIp()
1789  << std::endl;
1790  handleBaseOverlayMessage(tempMsg);
1791  } else {
1792  EV << "[BaseOverlay::internalHandleRpcTimeout() @ "
1793  << thisNode.getIp()
1794  << " (" << thisNode.getKey().toString(16) << ")]\n"
1795  << " dropping msg for " << dest
1796  << endl;
1797  RECORD_STATS(numDropped++;
1798  bytesDropped += tempMsg->getByteLength());
1799  delete tempMsg;
1800  }
1801  } else {
1802  RECORD_STATS(numDropped++;
1803  bytesDropped += tempMsg->getByteLength());
1804  //std::cout << thisNode.getIp() << " BaseOverlay::internalHandleRpcTimeout() 2 " << msg->getName() << std::endl;
1805  delete tempMsg;
1806  join();
1807  }
1808  break;
1809  }
1810  RPC_SWITCH_END( )
1811 
1812  BaseRpc::internalHandleRpcTimeout(msg, dest, context, rpcId, destKey);
1813 }
1814 
1816  const OverlayKey& destKey,
1817  const std::vector<TransportAddress>&
1818  sourceRoute,
1819  RoutingType routingType) {
1820  FindNodeCall* findNodeCall;
1821  uint32_t numSiblings = 1;
1822  if ((findNodeCall = dynamic_cast<FindNodeCall*>(message)))
1823  numSiblings = findNodeCall->getNumSiblings();
1824 
1825  sendToKey(destKey, message, numSiblings, sourceRoute, routingType);
1826 }
1827 
1829  BaseResponseMessage* response)
1830 {
1831  OverlayCtrlInfo* overlayCtrlInfo =
1832  check_and_cast<OverlayCtrlInfo*>(call->getControlInfo());
1833 
1834  TransportType transportType = ROUTE_TRANSPORT;
1835  const TransportAddress* destNode;
1836  if (overlayCtrlInfo->getSrcNode().isUnspecified()) {
1837  if (sendRpcResponseToLastHop) {
1838  // used for KBR protocols to deal with NATs
1839  // (srcNode in call message may contain private IP address)
1840  destNode = &(overlayCtrlInfo->getLastHop());
1841  } else {
1842  // used for non-KBR protocols which have to route RPC calls
1843  // but can't use BaseRouteMessage (this doesn't work with NATs)
1844  destNode = &(call->getSrcNode());
1845  }
1846  } else {
1847  destNode = &(overlayCtrlInfo->getSrcNode());
1848  }
1849  const OverlayKey* destKey = &OverlayKey::UNSPECIFIED_KEY;
1850 
1851  RoutingType routingType
1852  = static_cast<RoutingType>(overlayCtrlInfo->getRoutingType());
1853 
1854  assert(overlayCtrlInfo->getTransportType() != INTERNAL_TRANSPORT);
1855 
1856  if ((overlayCtrlInfo->getTransportType() == UDP_TRANSPORT) ||
1857  (routingType == SEMI_RECURSIVE_ROUTING) ||
1858  (routingType == ITERATIVE_ROUTING) ||
1859  (routingType == EXHAUSTIVE_ITERATIVE_ROUTING)
1860  ) {
1861  // received by UDP or direct response (IR, EIR or SRR routing)
1862  transportType = UDP_TRANSPORT;
1863  overlayCtrlInfo->setVisitedHopsArraySize(0); //???
1864  } else if ((static_cast<RoutingType> (overlayCtrlInfo->getRoutingType())
1865  == FULL_RECURSIVE_ROUTING)) {
1866  // full recursive routing
1867  destKey = &(overlayCtrlInfo->getSrcNode().getKey());
1868  destNode = &NodeHandle::UNSPECIFIED_NODE;
1869  }
1870  // else: source routing -> route back over visited hops
1871 
1872  sendRpcResponse(transportType,
1873  static_cast<CompType>(overlayCtrlInfo->getSrcComp()),
1874  *destNode, *destKey, call, response);
1875 }
1876 
1877 //protected: statistic helpers for IterativeLookup
1879 {
1880  RECORD_STATS(numFindNodeSent++;
1881  bytesFindNodeSent += call->getByteLength());
1882 }
1883 
1885 {
1886  RECORD_STATS(numFailedNodeSent++;
1887  bytesFailedNodeSent += call->getByteLength());
1888 }
1889 
1890 //private: rpc stub
1892 {
1893  // if this node is malicious don't answer a findNodeCall
1894  if (isMalicious() && dropFindNodeAttack) {
1895  EV << "[BaseOverlay::findNodeRpc() @ " << thisNode.getIp()
1896  << " (" << thisNode.getKey().toString(16) << ")]\n"
1897  << " Node ignores findNodeCall because this node is malicious"
1898  << endl;
1899  delete call;
1900  return;
1901  }
1902 
1903  FindNodeResponse* findNodeResponse =
1904  new FindNodeResponse("FindNodeResponse");
1905 
1906  findNodeResponse->setBitLength(FINDNODERESPONSE_L(findNodeResponse));
1907  NodeVector* nextHops = findNode(call->getLookupKey(),
1908  call->getNumRedundantNodes(),
1909  call->getExhaustiveIterative() ? -1 : call->getNumSiblings(), call);
1910 
1911  findNodeResponse->setClosestNodesArraySize(nextHops->size());
1912  for (uint32_t i=0; i < nextHops->size(); i++) {
1913  findNodeResponse->setClosestNodes(i, (*nextHops)[i]);
1914  }
1915 
1916  bool err;
1917  if (!call->getExhaustiveIterative() &&
1918  isSiblingFor(thisNode, call->getLookupKey(), call->getNumSiblings(),
1919  &err)) {
1920  findNodeResponse->setSiblings(true);
1921  }
1922 
1923  if (isMalicious() && invalidNodesAttack) {
1924  if (isSiblingAttack) {
1925  findNodeResponse->setSiblings(true);
1926  } else {
1927  findNodeResponse->setSiblings(false);
1928  }
1929 
1930  int resultSize = isSiblingAttack ? call->getNumSiblings() :
1931  call->getNumRedundantNodes();
1932 
1933  findNodeResponse->setClosestNodesArraySize(resultSize);
1934  for (int i = 0; i < resultSize; i++) {
1935  findNodeResponse->setClosestNodes(i,
1936  NodeHandle(call->getLookupKey() + i, IPvXAddress(IPAddress(
1937  isSiblingAttack ? (424242+i) : intuniform(42,123123))), 42));
1938 #if 0
1939  // was not used for evaluation
1940  if ((i == 0) && isSiblingAttack) {
1941  findNodeResponse->setClosestNodes(0, thisNode);
1942  }
1943 #endif
1944  }
1945  } else if (isMalicious() && isSiblingAttack) {
1946  findNodeResponse->setSiblings(true);
1947  findNodeResponse->setClosestNodesArraySize(1);
1948  findNodeResponse->setClosestNodes(0, thisNode);
1949  }
1950 
1951  findNodeResponse->setBitLength(FINDNODERESPONSE_L(findNodeResponse));
1952 
1953  if (call->hasObject("findNodeExt")) {
1954  cPacket* findNodeExt = check_and_cast<cPacket*>(call->removeObject("findNodeExt"));
1955  findNodeResponse->addObject(findNodeExt);
1956  findNodeResponse->addBitLength(findNodeExt->getBitLength());
1957  }
1958 
1959  RECORD_STATS(numFindNodeResponseSent++; bytesFindNodeResponseSent +=
1960  findNodeResponse->getByteLength());
1961 
1962  delete nextHops;
1963 
1964  sendRpcResponse(call, findNodeResponse);
1965 }
1966 
1967 
1969 {
1970  FailedNodeResponse* failedNodeResponse =
1971  new FailedNodeResponse("FailedNodeResponse");
1972  failedNodeResponse->setTryAgain(handleFailedNode(call->getFailedNode()));
1973  failedNodeResponse->setBitLength(FAILEDNODERESPONSE_L(failedNodeResponse));
1974 
1975  if (call->hasObject("findNodeExt")) {
1976  cPacket* findNodeExt = check_and_cast<cPacket*>(
1977  call->removeObject("findNodeExt"));
1978  failedNodeResponse->addObject(findNodeExt);
1979  failedNodeResponse->addBitLength(findNodeExt->getBitLength());
1980  }
1981 
1982  RECORD_STATS(numFailedNodeResponseSent++; bytesFailedNodeResponseSent +=
1983  failedNodeResponse->getByteLength());
1984 
1985  sendRpcResponse(call, failedNodeResponse);
1986 }
1987 
1989 {
1990  int numSiblings = call->getNumSiblings();
1991 
1992  if (numSiblings < 0) {
1993  numSiblings = getMaxNumSiblings();
1994  }
1995 
1996  if (internalReadyState == false) {
1997  // overlay not ready => lookup failed
1998  EV << "[BaseOverlay::lookupRpc() @ "
1999  << getThisNode().getIp()
2000  << " (" << getThisNode().getKey().toString(16) << ")]\n"
2001  << " LookupCall "
2002  << call->getNonce()
2003  << " failed, because overlay module is not ready!" << endl;
2004 
2005  LookupResponse* response = new LookupResponse();
2006  response->setKey(call->getKey());
2007  response->setIsValid(false);
2008 
2009  sendRpcResponse(call, response);
2010 
2011  return;
2012  }
2013 
2014  // create lookup and sent to key
2015  AbstractLookup* lookup = createLookup(static_cast<RoutingType>(
2016  call->getRoutingType()), call, NULL, true);
2017  lookup->lookup(call->getKey(), numSiblings, hopCountMax,
2018  1, new SendToKeyListener( this, call ));
2019 }
2020 
2022 {
2023  if (state != READY) {
2024  //TODO EV...
2025  //std::cout << "BaseOverlay::nextHopRpc() (state != READY) " << state << " " << call->getName() << std::endl;
2026  //delete call;
2027  //return;
2028  }
2029 
2030  BaseRouteMessage* routeMsg
2031  = check_and_cast<BaseRouteMessage*>(call->decapsulate());
2032 
2033  OverlayCtrlInfo* overlayCtrlInfo =
2034  check_and_cast<OverlayCtrlInfo*>(call->getControlInfo()->dup());
2035  overlayCtrlInfo->setHopCount(routeMsg->getHopCount());
2036  overlayCtrlInfo->setSrcNode(routeMsg->getSrcNode());
2037  overlayCtrlInfo->setRoutingType(routeMsg->getRoutingType());
2038 
2039  routeMsg->setControlInfo(overlayCtrlInfo);
2040  assert(routeMsg->getControlInfo());
2041 
2042  std::string temp("ACK: [");
2043  (temp += routeMsg->getName()) += "]";
2044 
2045  handleBaseOverlayMessage(routeMsg, routeMsg->getDestKey());
2046 
2047  NextHopResponse* response
2048  = new NextHopResponse(temp.c_str());
2049  response->setBitLength(NEXTHOPRESPONSE_L(response));
2050  sendRpcResponse(call, response);
2051 }
2052 
2053 void BaseOverlay::registerComp(CompType compType, cModule *module)
2054 {
2055  cGate *gate = NULL;
2056 
2057  if (module != NULL) {
2058  gate = module->gate("direct_in");
2059  if (gate == NULL) {
2060  throw cRuntimeError("BaseOverlay::registerComp(): The module "
2061  "which tried to register has "
2062  "no direct_in gate!");
2063  }
2064  }
2065 
2066  compModuleList[compType] = make_pair<cModule*, cGate*>(module, gate);
2067 }
2068 
2070 {
2071  CompModuleList::iterator it = compModuleList.find(compType);
2072 
2073  if (it != compModuleList.end())
2074  return it->second.first;
2075  else
2076  return NULL;
2077 }
2078 
2080 {
2081  CompModuleList::iterator it = compModuleList.find(compType);
2082 
2083  if (it != compModuleList.end())
2084  return it->second.second;
2085  else
2086  return NULL;
2087 }
2088 
2089 void BaseOverlay::sendMessageToAllComp(cMessage* msg, CompType srcComp)
2090 {
2091  Enter_Method_Silent();
2092  take(msg);
2093 
2094  for (CompModuleList::iterator it = compModuleList.begin();
2095  it != compModuleList.end(); it++) {
2096 
2097  // don't send message to the origination component
2098  if (it->first != srcComp)
2099  sendDirect((cMessage*)msg->dup(), it->second.second);
2100  }
2101 
2102  delete msg;
2103 }
2104 
2106 {
2107  return isVector() || getParentModule()->isVector();
2108 }
2109