00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00028 #include <cassert>
00029
00030 #include <RpcMacros.h>
00031
00032 #include <UDPAppBase.h>
00033 #include <UDPSocket.h>
00034 #include <IPAddressResolver.h>
00035 #include <NotificationBoard.h>
00036
00037 #include <GlobalNodeListAccess.h>
00038 #include <UnderlayConfiguratorAccess.h>
00039 #include <GlobalStatisticsAccess.h>
00040 #include <GlobalParametersAccess.h>
00041
00042 #include <LookupListener.h>
00043 #include <RecursiveLookup.h>
00044 #include <IterativeLookup.h>
00045
00046 #include <BootstrapList.h>
00047
00048 #include "BaseOverlay.h"
00049
00050 using namespace std;
00051
00052
00053
00054
00055
00056
00057 BaseOverlay::BaseOverlay()
00058 {
00059 globalNodeList = NULL;
00060 underlayConfigurator = NULL;
00061 notificationBoard = NULL;
00062 globalParameters = NULL;
00063 bootstrapList = NULL;
00064 }
00065
00066 BaseOverlay::~BaseOverlay()
00067 {
00068 finishLookups();
00069 finishRpcs();
00070 }
00071
00072 int BaseOverlay::numInitStages() const
00073 {
00074 return NUM_STAGES_ALL;
00075 }
00076
00077 void BaseOverlay::initialize(int stage)
00078 {
00079 if (stage == MIN_STAGE_OVERLAY) {
00080 OverlayKey::setKeyLength(par("keyLength"));
00081
00082
00083 globalNodeList = GlobalNodeListAccess().get();
00084 underlayConfigurator = UnderlayConfiguratorAccess().get();
00085 notificationBoard = NotificationBoardAccess().get();
00086 globalParameters = GlobalParametersAccess().get();
00087 bootstrapList = check_and_cast<BootstrapList*>(getParentModule()->
00088 getParentModule()->getSubmodule("bootstrapList", 0));
00089
00090 udpGate = gate("udpIn");
00091 appGate = gate("appIn");
00092
00093
00094 debugOutput = par("debugOutput");
00095 collectPerHopDelay = par("collectPerHopDelay");
00096 localPort = par("localPort");
00097 hopCountMax = par("hopCountMax");
00098 drawOverlayTopology = par("drawOverlayTopology");
00099 rejoinOnFailure = par("rejoinOnFailure");
00100
00101
00102 kbr = false;
00103
00104
00105 std::string temp = par("routingType").stdstringValue();
00106 if (temp == "iterative")
00107 defaultRoutingType = ITERATIVE_ROUTING;
00108 else if (temp == "exhaustive-iterative")
00109 defaultRoutingType = EXHAUSTIVE_ITERATIVE_ROUTING;
00110 else if (temp == "semi-recursive")
00111 defaultRoutingType = SEMI_RECURSIVE_ROUTING;
00112 else if (temp == "full-recursive")
00113 defaultRoutingType = FULL_RECURSIVE_ROUTING;
00114 else if (temp == "source-routing-recursive")
00115 defaultRoutingType = RECURSIVE_SOURCE_ROUTING;
00116 else throw cRuntimeError((std::string("Wrong routing type: ")
00117 + temp).c_str());
00118
00119 useCommonAPIforward = par("useCommonAPIforward");
00120 routeMsgAcks = par("routeMsgAcks");
00121 recNumRedundantNodes = par("recNumRedundantNodes");
00122 recordRoute = par("recordRoute");
00123
00124
00125 iterativeLookupConfig.redundantNodes = par("lookupRedundantNodes");
00126 iterativeLookupConfig.parallelPaths = par("lookupParallelPaths");
00127 iterativeLookupConfig.parallelRpcs = par("lookupParallelRpcs");
00128 iterativeLookupConfig.secure = par("lookupSecure");
00129 iterativeLookupConfig.merge = par("lookupMerge");
00130 iterativeLookupConfig.failedNodeRpcs = par("lookupFailedNodeRpcs");
00131 iterativeLookupConfig.strictParallelRpcs =
00132 par("lookupStrictParallelRpcs");
00133 iterativeLookupConfig.useAllParallelResponses =
00134 par("lookupUseAllParallelResponses");
00135 iterativeLookupConfig.newRpcOnEveryTimeout =
00136 par("lookupNewRpcOnEveryTimeout");
00137 iterativeLookupConfig.newRpcOnEveryResponse =
00138 par("lookupNewRpcOnEveryResponse");
00139 iterativeLookupConfig.finishOnFirstUnchanged =
00140 par("lookupFinishOnFirstUnchanged");
00141 iterativeLookupConfig.visitOnlyOnce =
00142 par("lookupVisitOnlyOnce");
00143
00144 recursiveLookupConfig.redundantNodes = par("lookupRedundantNodes");
00145 recursiveLookupConfig.numRetries = 0;
00146
00147
00148 numAppDataSent = 0;
00149 bytesAppDataSent = 0;
00150 numAppLookupSent = 0;
00151 bytesAppLookupSent = 0;
00152 numMaintenanceSent = 0;
00153 bytesMaintenanceSent = 0;
00154 numAppDataReceived = 0;
00155 bytesAppDataReceived = 0;
00156 numAppLookupReceived = 0;
00157 bytesAppLookupReceived = 0;
00158 numMaintenanceReceived = 0;
00159 bytesMaintenanceReceived = 0;
00160 numAppDataForwarded = 0;
00161 bytesAppDataForwarded = 0;
00162 numAppLookupForwarded = 0;
00163 bytesAppLookupForwarded = 0;
00164 numMaintenanceForwarded = 0;
00165 bytesMaintenanceForwarded = 0;
00166
00167 numDropped = 0;
00168 bytesDropped = 0;
00169 numFindNodeSent = 0;
00170 bytesFindNodeSent = 0;
00171 numFindNodeResponseSent = 0;
00172 bytesFindNodeResponseSent = 0;
00173 numFailedNodeSent = 0;
00174 bytesFailedNodeSent = 0;
00175 numFailedNodeResponseSent = 0;
00176 bytesFailedNodeResponseSent = 0;
00177
00178 joinRetries = 0;
00179
00180 numInternalSent = 0;
00181 bytesInternalSent = 0;
00182 numInternalReceived = 0;
00183 bytesInternalReceived = 0;
00184
00185 WATCH(numAppDataSent);
00186 WATCH(bytesAppDataSent);
00187 WATCH(numAppLookupSent);
00188 WATCH(bytesAppLookupSent);
00189 WATCH(numMaintenanceSent);
00190 WATCH(bytesMaintenanceSent);
00191 WATCH(numAppDataReceived);
00192 WATCH(bytesAppDataReceived);
00193 WATCH(numAppLookupReceived);
00194 WATCH(bytesAppLookupReceived);
00195 WATCH(numMaintenanceReceived);
00196 WATCH(bytesMaintenanceReceived);
00197 WATCH(numAppDataForwarded);
00198 WATCH(bytesAppDataForwarded);
00199 WATCH(numAppLookupForwarded);
00200 WATCH(bytesAppLookupForwarded);
00201 WATCH(numMaintenanceForwarded);
00202 WATCH(bytesMaintenanceForwarded);
00203
00204 WATCH(numDropped);
00205 WATCH(bytesDropped);
00206 WATCH(numFindNodeSent);
00207 WATCH(bytesFindNodeSent);
00208 WATCH(numFindNodeResponseSent);
00209 WATCH(bytesFindNodeResponseSent);
00210 WATCH(numFailedNodeSent);
00211 WATCH(bytesFailedNodeSent);
00212 WATCH(numFailedNodeResponseSent);
00213 WATCH(bytesFailedNodeResponseSent);
00214
00215 WATCH(joinRetries);
00216
00217 if (isInSimpleMultiOverlayHost()) {
00218 WATCH(numInternalSent);
00219 WATCH(bytesInternalSent);
00220 WATCH(numInternalReceived);
00221 WATCH(bytesInternalReceived);
00222 }
00223
00224
00225 thisNode.setAddress(IPAddressResolver().
00226 addressOf(getParentModule()->getParentModule()).get4());
00227 thisNode.setKey(OverlayKey::UNSPECIFIED_KEY);
00228
00229 state = INIT;
00230 internalReadyState = false;
00231 getDisplayString().setTagArg("i", 1, "red");
00232 globalNodeList->setOverlayReadyIcon(getThisNode(), false);
00233
00234
00235 bindToPort(localPort);
00236
00237
00238 notificationBoard->subscribe(this, NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
00239 notificationBoard->subscribe(this, NF_OVERLAY_NODE_LEAVE);
00240 notificationBoard->subscribe(this, NF_OVERLAY_NODE_GRACEFUL_LEAVE);
00241
00242
00243 if (drawOverlayTopology)
00244 initVis(getParentModule()->getParentModule());
00245
00246
00247 initRpcs();
00248 initLookups();
00249
00250
00251 globalStatistics->nodesInitialized++;
00252 creationTime = simTime();
00253 WATCH(creationTime);
00254 }
00255
00256 if (stage >= MIN_STAGE_OVERLAY && stage <= MAX_STAGE_OVERLAY)
00257 initializeOverlay(stage);
00258
00259 if (stage == MAX_STAGE_TIER_1) {
00260
00261
00262
00263 if (!compModuleList.count(BOOTSTRAPLIST_COMP)) {
00264 BaseOverlay *firstOverlay = dynamic_cast<BaseOverlay*>
00265 (getParentModule()->getParentModule()
00266 ->getSubmodule("overlay", 0)->gate("appIn")
00267 ->getNextGate()->getOwnerModule());
00268 if (!firstOverlay) {
00269 throw cRuntimeError("BaseOverlay.cc: "
00270 "Couldn't obtain bootstrap gate");
00271 }
00272 registerComp(BOOTSTRAPLIST_COMP,
00273 firstOverlay->getCompModule(BOOTSTRAPLIST_COMP));
00274 }
00275 }
00276
00277
00278 if (stage == MAX_STAGE_TIER_3) {
00279 if ((bool)par("joinOnApplicationRequest") == false) {
00280 join();
00281 }
00282 }
00283 }
00284
00285 void BaseOverlay::initializeOverlay(int stage)
00286 {
00287 }
00288
00289 void BaseOverlay::finish()
00290 {
00291 finishOverlay();
00292
00293 globalStatistics->nodesFinished++;
00294
00295 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00296
00297 if (time >= GlobalStatistics::MIN_MEASURED) {
00298
00299 if (collectPerHopDelay) {
00300 std::ostringstream singleHopName;
00301 HopDelayRecord* hdrl = NULL;
00302 HopDelayRecord* hdr = NULL;
00303 for (size_t i = 0; i < singleHopDelays.size();) {
00304 hdrl = singleHopDelays[i++];
00305 hdr = hdrl;
00306 for (size_t j = 1; j <= i; ++j) {
00307 if (hdr->count == 0) continue;
00308 singleHopName.str("");
00309 singleHopName << "BaseOverlay: Average Delay in Hop "
00310 << j << " of " << i;
00311 globalStatistics->addStdDev(singleHopName.str(),
00312 SIMTIME_DBL(hdr->val / hdr->count));
00313 ++hdr;
00314 }
00315 delete[] hdrl;
00316 }
00317 singleHopDelays.clear();
00318 }
00319
00320 globalStatistics->addStdDev("BaseOverlay: Join Retries", joinRetries);
00321
00322 globalStatistics->addStdDev("BaseOverlay: Sent App Data Messages/s",
00323 numAppDataSent / time);
00324 globalStatistics->addStdDev("BaseOverlay: Sent App Data Bytes/s",
00325 bytesAppDataSent / time);
00326 if (isInSimpleMultiOverlayHost()) {
00327 globalStatistics->addStdDev("BaseOverlay: Internal Sent Messages/s",
00328 numInternalReceived / time);
00329 globalStatistics->addStdDev("BaseOverlay: Internal Sent Bytes/s",
00330 bytesInternalReceived / time);
00331 }
00332 globalStatistics->addStdDev("BaseOverlay: Sent App Lookup Messages/s",
00333 numAppLookupSent / time);
00334 globalStatistics->addStdDev("BaseOverlay: Sent App Lookup Bytes/s",
00335 bytesAppLookupSent / time);
00336 globalStatistics->addStdDev("BaseOverlay: Sent Maintenance Messages/s",
00337 numMaintenanceSent / time);
00338 globalStatistics->addStdDev("BaseOverlay: Sent Maintenance Bytes/s",
00339 bytesMaintenanceSent / time);
00340
00341 globalStatistics->addStdDev("BaseOverlay: Sent Total Messages/s",
00342 (numAppDataSent + numAppLookupSent +
00343 numMaintenanceSent) / time);
00344 globalStatistics->addStdDev("BaseOverlay: Sent Total Bytes/s",
00345 (bytesAppDataSent + bytesAppLookupSent +
00346 bytesMaintenanceSent) / time);
00347 globalStatistics->addStdDev("BaseOverlay: Sent FindNode Messages/s",
00348 numFindNodeSent / time);
00349 globalStatistics->addStdDev("BaseOverlay: Sent FindNode Bytes/s",
00350 bytesFindNodeSent / time);
00351
00352 globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Messages/s",
00353 numFindNodeResponseSent / time);
00354 globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Bytes/s",
00355 bytesFindNodeResponseSent / time);
00356 globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Messages/s",
00357 numFailedNodeSent / time);
00358 globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Bytes/s",
00359 bytesFailedNodeSent / time);
00360 globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Messages/s",
00361 numFailedNodeResponseSent / time);
00362 globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Bytes/s",
00363 bytesFailedNodeResponseSent / time);
00364 globalStatistics->addStdDev("BaseOverlay: Received App Data Messages/s",
00365 numAppDataReceived / time);
00366 globalStatistics->addStdDev("BaseOverlay: Received App Data Bytes/s",
00367 bytesAppDataReceived / time);
00368 if (isInSimpleMultiOverlayHost()) {
00369 globalStatistics->addStdDev("BaseOverlay: Internal Received Messages/s",
00370 numInternalReceived / time);
00371 globalStatistics->addStdDev("BaseOverlay: Internal Received Bytes/s",
00372 bytesInternalReceived / time);
00373 }
00374 globalStatistics->addStdDev("BaseOverlay: Received App Lookup Messages/s",
00375 numAppLookupReceived / time);
00376 globalStatistics->addStdDev("BaseOverlay: Received App Lookup Bytes/s",
00377 bytesAppLookupReceived / time);
00378 globalStatistics->addStdDev("BaseOverlay: Received Maintenance Messages/s",
00379 numMaintenanceReceived / time);
00380 globalStatistics->addStdDev("BaseOverlay: Received Maintenance Bytes/s",
00381 bytesMaintenanceReceived / time);
00382
00383 globalStatistics->addStdDev("BaseOverlay: Received Total Messages/s",
00384 (numAppDataReceived + numAppLookupReceived +
00385 numMaintenanceReceived)/time);
00386 globalStatistics->addStdDev("BaseOverlay: Received Total Bytes/s",
00387 (bytesAppDataReceived + bytesAppLookupReceived +
00388 bytesMaintenanceReceived)/time);
00389 globalStatistics->addStdDev("BaseOverlay: Forwarded App Data Messages/s",
00390 numAppDataForwarded / time);
00391 globalStatistics->addStdDev("BaseOverlay: Forwarded App Data Bytes/s",
00392 bytesAppDataForwarded / time);
00393 globalStatistics->addStdDev("BaseOverlay: Forwarded App Lookup Messages/s",
00394 numAppLookupForwarded / time);
00395 globalStatistics->addStdDev("BaseOverlay: Forwarded App Lookup Bytes/s",
00396 bytesAppLookupForwarded / time);
00397 globalStatistics->addStdDev("BaseOverlay: Forwarded Maintenance Messages/s",
00398 numMaintenanceForwarded / time);
00399 globalStatistics->addStdDev("BaseOverlay: Forwarded Maintenance Bytes/s",
00400 bytesMaintenanceForwarded / time);
00401 globalStatistics->addStdDev("BaseOverlay: Forwarded Total Messages/s",
00402 (numAppDataForwarded + numAppLookupForwarded +
00403 numMaintenanceForwarded) / time);
00404 globalStatistics->addStdDev("BaseOverlay: Forwarded Total Bytes/s",
00405 (bytesAppDataForwarded + bytesAppLookupForwarded +
00406 bytesMaintenanceForwarded) / time);
00407
00408 globalStatistics->addStdDev("BaseOverlay: Dropped Messages/s",
00409 numDropped / time);
00410 globalStatistics->addStdDev("BaseOverlay: Dropped Bytes/s",
00411 bytesDropped / time);
00412
00413 globalStatistics->addStdDev("BaseOverlay: Measured Session Time",
00414 SIMTIME_DBL(simTime() - creationTime));
00415
00416 globalStatistics->addStdDev("BaseRpc: Sent Ping Messages/s",
00417 numPingSent / time);
00418 globalStatistics->addStdDev("BaseRpc: Sent Ping Bytes/s",
00419 bytesPingSent / time);
00420 globalStatistics->addStdDev("BaseRpc: Sent Ping Response Messages/s",
00421 numPingResponseSent / time);
00422 globalStatistics->addStdDev("BaseRpc: Sent Ping Response Bytes/s",
00423 bytesPingResponseSent / time);
00424 }
00425
00426 globalStatistics->doFinish();
00427
00428 }
00429
00430 void BaseOverlay::finishOverlay()
00431 {
00432 }
00433
00434
00435
00436
00437 bool BaseOverlay::isMalicious()
00438 {
00439 return globalNodeList->isMalicious(getThisNode());
00440 }
00441
00442 CompType BaseOverlay::getThisCompType()
00443 {
00444 return OVERLAY_COMP;
00445 }
00446
00447
00448
00449
00450 void BaseOverlay::bindToPort(int port)
00451 {
00452 EV << "[BaseOverlay::bindToPort() @ " << thisNode.getAddress()
00453 << " (" << thisNode.getKey().toString(16) << ")]\n"
00454 << " Binding to UDP port " << port
00455 << endl;
00456
00457 thisNode.setPort(port);
00458
00459
00460
00461 cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00462 UDPControlInfo *ctrl = new UDPControlInfo();
00463 ctrl->setSrcPort(port);
00464 ctrl->setSockId(UDPSocket::generateSocketId());
00465 msg->setControlInfo(ctrl);
00466 send(msg, "udpOut");
00467 }
00468
00469
00470
00471
00472
00473
00474 void BaseOverlay::callDeliver(BaseOverlayMessage* msg,
00475 const OverlayKey& destKey)
00476 {
00477 KBRdeliver* deliverMsg = new KBRdeliver();
00478
00479 OverlayCtrlInfo* overlayCtrlInfo =
00480 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
00481
00482 BaseAppDataMessage* appDataMsg = dynamic_cast<BaseAppDataMessage*>(msg);
00483
00484
00485 if (appDataMsg != NULL) {
00486 overlayCtrlInfo->setSrcComp(appDataMsg->getSrcComp());
00487 overlayCtrlInfo->setDestComp(appDataMsg->getDestComp());
00488 }
00489
00490 deliverMsg->setControlInfo(overlayCtrlInfo);
00491 deliverMsg->setDestKey(destKey);
00492 deliverMsg->encapsulate(msg->decapsulate());
00493 deliverMsg->setType(KBR_DELIVER);
00494
00495 cGate* destGate = getCompRpcGate(static_cast<CompType>(
00496 overlayCtrlInfo->getDestComp()));
00497
00498 if (destGate == NULL) {
00499 throw cRuntimeError("BaseOverlay::callDeliver(): Unknown destComp!");
00500 }
00501
00502 sendDirect(deliverMsg, destGate);
00503
00504 delete msg;
00505 }
00506
00507 void BaseOverlay::callForward(const OverlayKey& key, BaseRouteMessage* msg,
00508 const NodeHandle& nextHopNode)
00509 {
00510 KBRforward* forwardMsg = new KBRforward();
00511
00512 forwardMsg->setDestKey(msg->getDestKey());
00513 forwardMsg->setNextHopNode(nextHopNode);
00514 forwardMsg->encapsulate(msg->getEncapsulatedMsg()->decapsulate());
00515
00516 OverlayCtrlInfo* overlayCtrlInfo =
00517 new OverlayCtrlInfo();
00518 overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00519 overlayCtrlInfo->setRoutingType(msg->getRoutingType());
00520 overlayCtrlInfo->setHopCount(msg->getHopCount());
00521 overlayCtrlInfo->setSrcNode(msg->getSrcNode());
00522 overlayCtrlInfo->setSrcComp(check_and_cast<BaseAppDataMessage*>
00523 (msg->getEncapsulatedMsg())->getSrcComp());
00524 overlayCtrlInfo->setDestComp(check_and_cast<BaseAppDataMessage*>
00525 (msg->getEncapsulatedMsg())->getDestComp());
00526
00527 if (msg->getControlInfo() != NULL) {
00528 OverlayCtrlInfo* ctrlInfo =
00529 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
00530
00531 overlayCtrlInfo->setLastHop(ctrlInfo->getLastHop());
00532
00533 delete ctrlInfo;
00534 }
00535
00536 forwardMsg->setControlInfo(overlayCtrlInfo);
00537
00538 forwardMsg->setType(KBR_FORWARD);
00539
00540 send(forwardMsg, "appOut");
00541
00542 delete msg;
00543 }
00544
00545 NodeVector* BaseOverlay::local_lookup(const OverlayKey& key,
00546 int num, bool safe)
00547 {
00548 Enter_Method("local_lookup()");
00549
00550 if (safe == true) {
00551 throw cRuntimeError("BaseOverlay::local_lookup(): "
00552 "safe flag is not implemented!");
00553 }
00554
00555 if (num < 0) num = INT_MAX;
00556 NodeVector* nodeVector = findNode(key, min(num, getMaxNumRedundantNodes()),
00557 min(num,getMaxNumSiblings()));
00558
00559 if (((int)nodeVector->size()) > num)
00560 nodeVector->resize(num);
00561
00562 return nodeVector;
00563 }
00564
00565 void BaseOverlay::join(const OverlayKey& nodeID)
00566 {
00567 Enter_Method("join()");
00568
00569 joinRetries++;
00570
00571 if (((state == READY) || (state == FAILED)) && !rejoinOnFailure) {
00572 state = FAILED;
00573 return;
00574 }
00575
00576 if (state != READY) {
00577
00578 thisNode.setAddress(
00579 IPAddressResolver().addressOf(getParentModule()->getParentModule()).get4());
00580
00581 if (!nodeID.isUnspecified()) {
00582 thisNode.setKey(nodeID);
00583 } else if (thisNode.getKey().isUnspecified()) {
00584 std::string nodeIdStr = par("nodeId").stdstringValue();
00585
00586 if (nodeIdStr.size()) {
00587
00588 thisNode.setKey(OverlayKey(nodeIdStr));
00589 } else {
00590 setOwnNodeID();
00591 }
00592 }
00593 }
00594
00595 joinOverlay();
00596 }
00597
00598 void BaseOverlay::joinForeignPartition(const NodeHandle& node)
00599 {
00600 throw cRuntimeError("BaseOverlay::joinForeignPartition(): "
00601 "This overlay doesn't support merging!");
00602 }
00603
00604 void BaseOverlay::setOwnNodeID()
00605 {
00606 thisNode.setKey(OverlayKey::random());
00607 }
00608
00609 NodeVector* BaseOverlay::neighborSet(int num)
00610 {
00611 Enter_Method("neighborSet()");
00612
00613 return local_lookup(thisNode.getKey(), num, false);
00614 }
00615
00616 void BaseOverlay::callUpdate(const NodeHandle& node, bool joined)
00617 {
00618 if ((!node.isUnspecified()) && (node != thisNode)) {
00619 if (joined) {
00620 EV << "[BaseOverlay::callUpdate() @ " << thisNode.getAddress()
00621 << " (" << thisNode.getKey().toString(16) << ")]\n"
00622 << " (" << node << ", " << joined << ") joined"
00623 << endl;
00624 } else {
00625 EV << "[BaseOverlay::callUpdate() @ " << thisNode.getAddress()
00626 << " (" << thisNode.getKey().toString(16) << ")]\n"
00627 << " (" << node << ", " << joined << ") left"
00628 << endl;
00629 }
00630 }
00631
00632 KBRupdate* updateMsg = new KBRupdate("UPDATE");
00633
00634 updateMsg->setNode(node);
00635 updateMsg->setJoined(joined);
00636
00637 updateMsg->setType(KBR_UPDATE);
00638
00639 send(updateMsg, "appOut");
00640 }
00641
00642 bool BaseOverlay::isSiblingFor(const NodeHandle& node, const OverlayKey& key,
00643 int numSiblings, bool* err)
00644 {
00645 Enter_Method("isSiblingFor()");
00646
00647 throw cRuntimeError("isSiblingFor: Not implemented!");
00648
00649 return false;
00650 }
00651
00652 int BaseOverlay::getMaxNumSiblings()
00653 {
00654 Enter_Method("getMaxNumSiblings()");
00655
00656 throw cRuntimeError("getMaxNumSiblings: Not implemented!");
00657
00658 return false;
00659 }
00660
00661 int BaseOverlay::getMaxNumRedundantNodes()
00662 {
00663 Enter_Method("getMaxNumRedundantNodes()");
00664
00665 throw cRuntimeError("getMaxNumRedundantNodes: Not implemented!");
00666
00667 return false;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676 void BaseOverlay::handleMessage(cMessage* msg)
00677 {
00678 if (msg->getArrivalGate() == udpGate) {
00679 UDPControlInfo* udpControlInfo =
00680 check_and_cast<UDPControlInfo*>(msg->removeControlInfo());
00681 OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo;
00682 overlayCtrlInfo->setLastHop(TransportAddress(
00683 udpControlInfo->getSrcAddr(),
00684 udpControlInfo->getSrcPort()));
00685 overlayCtrlInfo->setSrcRoute(overlayCtrlInfo->getLastHop());
00686 overlayCtrlInfo->setTransportType(UDP_TRANSPORT);
00687
00688 msg->setControlInfo(overlayCtrlInfo);
00689 delete udpControlInfo;
00690
00691
00692 if (debugOutput) {
00693 EV << "[BaseOverlay:handleMessage() @ " << thisNode.getAddress()
00694 << " (" << thisNode.getKey().toString(16) << ")]\n"
00695 << " Received " << *msg << " from "
00696 << overlayCtrlInfo->getLastHop().getAddress() << endl;
00697 }
00698
00699 BaseOverlayMessage* baseOverlayMsg =
00700 dynamic_cast<BaseOverlayMessage*>(msg);
00701
00702 if (baseOverlayMsg == NULL) {
00703 cPacket* packet = check_and_cast<cPacket*>(msg);
00704 RECORD_STATS(numDropped++; bytesDropped += packet->getByteLength());
00705 delete msg;
00706 return;
00707 }
00708
00709
00710 if (overlayCtrlInfo->getLastHop() != thisNode) {
00711
00712 if (baseOverlayMsg->getStatType() == APP_DATA_STAT)
00713 RECORD_STATS(numAppDataReceived++; bytesAppDataReceived +=
00714 baseOverlayMsg->getByteLength());
00715 else if (baseOverlayMsg->getStatType() == APP_LOOKUP_STAT)
00716 RECORD_STATS(numAppLookupReceived++;bytesAppLookupReceived +=
00717 baseOverlayMsg->getByteLength());
00718 else
00719 RECORD_STATS(numMaintenanceReceived++;
00720 bytesMaintenanceReceived +=
00721 baseOverlayMsg->getByteLength());
00722 }
00723 if (overlayCtrlInfo->getLastHop().getAddress() == thisNode.getAddress()) {
00724
00725 RECORD_STATS(numInternalReceived++; bytesInternalReceived +=
00726 baseOverlayMsg->getByteLength());
00727 } else overlayCtrlInfo->setHopCount(1);
00728
00729
00730 if (!internalHandleMessage(msg)) {
00731 handleBaseOverlayMessage(baseOverlayMsg);
00732 }
00733 }
00734
00735 else if (internalHandleMessage(msg)) return;
00736
00737 else if (dynamic_cast<CommonAPIMessage*>(msg) != NULL) {
00738 if (dynamic_cast<KBRroute*>(msg) != NULL) {
00739 KBRroute* apiMsg = static_cast<KBRroute*>(msg);
00740
00741 std::vector<TransportAddress> sourceRoute;
00742 for (uint32_t i = 0; i < apiMsg->getSourceRouteArraySize(); ++i)
00743 sourceRoute.push_back(apiMsg->getSourceRoute(i));
00744
00745 route(apiMsg->getDestKey(), static_cast<CompType>(apiMsg->getDestComp()),
00746 static_cast<CompType>(apiMsg->getSrcComp()), apiMsg->decapsulate(),
00747 sourceRoute);
00748 } else if (dynamic_cast<KBRforward*>(msg) != NULL) {
00749 KBRforward* apiMsg = static_cast<KBRforward*>(msg);
00750 OverlayCtrlInfo* overlayCtrlInfo =
00751 check_and_cast<OverlayCtrlInfo*>
00752 (msg->removeControlInfo());
00753
00754 BaseAppDataMessage* dataMsg =
00755 new BaseAppDataMessage();
00756 dataMsg->setType(APPDATA);
00757 dataMsg->setBitLength(BASEAPPDATA_L(dataMsg));
00758 dataMsg->setName(apiMsg->getEncapsulatedMsg()->getName());
00759 dataMsg->encapsulate(apiMsg->decapsulate());
00760 dataMsg->setSrcComp(overlayCtrlInfo->getSrcComp());
00761 dataMsg->setDestComp(overlayCtrlInfo->getDestComp());
00762 dataMsg->setStatType(APP_DATA_STAT);
00763
00764 BaseRouteMessage* routeMsg = new BaseRouteMessage(dataMsg->getName());
00765 routeMsg->setType(OVERLAYROUTE);
00766 routeMsg->setBitLength(BASEROUTE_L(routeMsg));
00767 routeMsg->encapsulate(dataMsg);
00768
00769 routeMsg->setStatType(APP_DATA_STAT);
00770 routeMsg->setRoutingType(overlayCtrlInfo->getRoutingType());
00771 routeMsg->setDestKey(apiMsg->getDestKey());
00772 routeMsg->setSrcNode(overlayCtrlInfo->getSrcNode());
00773 routeMsg->setHopCount(overlayCtrlInfo->getHopCount());
00774 routeMsg->setControlInfo(overlayCtrlInfo);
00775
00776
00777 routeMsg->setContextPointer(this);
00778
00779 std::vector<TransportAddress> sourceRoute;
00780 sourceRoute.push_back(apiMsg->getNextHopNode());
00781 sendToKey(apiMsg->getDestKey(), routeMsg, 1, sourceRoute);
00782 }
00783
00784 delete msg;
00785 }
00786
00787
00788 else if (msg->getArrivalGate() == appGate) {
00789 handleAppMessage(msg);
00790 } else {
00791 throw cRuntimeError("BaseOverlay::handleMessage(): Received msg with "
00792 "unknown type!");
00793 delete msg;
00794 }
00795 }
00796
00797 void BaseOverlay::handleBaseOverlayMessage(BaseOverlayMessage* msg,
00798 const OverlayKey& destKey)
00799 {
00800 switch (msg->getType()) {
00801 case OVERLAYSIGNALING:
00802 handleUDPMessage(msg);
00803 return;
00804
00805 case RPC: {
00806
00807 BaseRpcMessage* rpcMsg = check_and_cast<BaseRpcMessage*>(msg);
00808
00809 internalHandleRpcMessage(rpcMsg);
00810 return;
00811 }
00812
00813 case APPDATA: {
00814
00815
00816 OverlayCtrlInfo* overlayCtrlInfo = check_and_cast<OverlayCtrlInfo*>(msg->getControlInfo());
00817 overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00818
00819 BaseAppDataMessage* baseAppDataMsg =
00820 check_and_cast<BaseAppDataMessage*>(msg);
00821 callDeliver(baseAppDataMsg, destKey);
00822 return;
00823 }
00824
00825 case OVERLAYROUTE: {
00826 BaseRouteMessage* baseRouteMsg =
00827 check_and_cast<BaseRouteMessage*>(msg);
00828
00829
00830 if (collectPerHopDelay) {
00831 baseRouteMsg->setHopDelayArraySize(baseRouteMsg->
00832 getHopDelayArraySize() + 1);
00833 baseRouteMsg->setHopDelay(baseRouteMsg->getHopDelayArraySize() - 1,
00834 simTime() - baseRouteMsg->getHopStamp());
00835 }
00836
00837 OverlayCtrlInfo* overlayCtrlInfo
00838 = check_and_cast<OverlayCtrlInfo*>(baseRouteMsg
00839 ->removeControlInfo());
00840
00841 overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00842
00843
00844 std::vector<TransportAddress> sourceRoute;
00845 if ((baseRouteMsg->getNextHopsArraySize() > 0) ||
00846 (baseRouteMsg->getRoutingType() == RECURSIVE_SOURCE_ROUTING) ||
00847 recordRoute) {
00848
00849 baseRouteMsg->setVisitedHopsArraySize(baseRouteMsg
00850 ->getVisitedHopsArraySize() + 1);
00851 baseRouteMsg->setVisitedHops(baseRouteMsg
00852 ->getVisitedHopsArraySize() - 1,
00853 overlayCtrlInfo->getLastHop());
00854
00855
00856 if (baseRouteMsg->getNextHopsArraySize() > 0) {
00857 sourceRoute.resize(baseRouteMsg->getNextHopsArraySize()- 1);
00858 for (uint32_t i = 1; i < baseRouteMsg->getNextHopsArraySize();
00859 ++i) {
00860 sourceRoute[i - 1] = baseRouteMsg->getNextHops(i);
00861 }
00862 baseRouteMsg->setNextHopsArraySize(0);
00863 }
00864 }
00865
00866
00867
00868 bool err;
00869 if ((sourceRoute.size() == 0) &&
00870 (baseRouteMsg->getDestKey().isUnspecified() ||
00871 isSiblingFor(thisNode, baseRouteMsg->getDestKey(), 1, &err)
00872 )) {
00873 overlayCtrlInfo->setHopCount(baseRouteMsg->getHopCount());
00874 overlayCtrlInfo->setSrcNode(baseRouteMsg->getSrcNode());
00875 overlayCtrlInfo->setRoutingType(baseRouteMsg->getRoutingType());
00876
00877 if (baseRouteMsg->getVisitedHopsArraySize() > 0) {
00878
00879 NodeHandle srcRoute(baseRouteMsg->getSrcNode().getKey(),
00880 baseRouteMsg->getVisitedHops(0));
00881
00882 for (uint32_t i = 0; i < baseRouteMsg->getVisitedHopsArraySize(); ++i) {
00883 srcRoute.appendSourceRoute(baseRouteMsg->getVisitedHops(i));
00884 }
00885
00886 overlayCtrlInfo->setSrcRoute(srcRoute);
00887 } else if (baseRouteMsg->getDestKey().isUnspecified()) {
00888
00889
00890 overlayCtrlInfo->setSrcRoute(
00891 NodeHandle(baseRouteMsg->getSrcNode().getKey(),
00892 overlayCtrlInfo->getLastHop()));
00893 } else {
00894
00895 overlayCtrlInfo->setSrcRoute(baseRouteMsg->getSrcNode());
00896 }
00897
00898
00899 overlayCtrlInfo->setVisitedHopsArraySize(
00900 baseRouteMsg->getVisitedHopsArraySize());
00901
00902 for (uint32_t i = 0; i < baseRouteMsg->getVisitedHopsArraySize();
00903 ++i) {
00904 overlayCtrlInfo->setVisitedHops(i,
00905 baseRouteMsg->getVisitedHops(i));
00906 }
00907
00908 BaseOverlayMessage* tmpMsg
00909 = check_and_cast<BaseOverlayMessage*>(baseRouteMsg
00910 ->decapsulate());
00911 tmpMsg->setControlInfo(overlayCtrlInfo);
00912
00913
00914 if (collectPerHopDelay) {
00915 RECORD_STATS(
00916 size_t i;
00917 for (i = singleHopDelays.size();
00918 i < baseRouteMsg->getHopDelayArraySize();) {
00919 singleHopDelays.push_back(new HopDelayRecord[++i]);
00920 }
00921
00922 i = baseRouteMsg->getHopDelayArraySize() - 1;
00923 HopDelayRecord* hdr = singleHopDelays[i];
00924
00925 for (size_t j = 0; j <= i; ++j) {
00926 hdr[j].count++;
00927 hdr[j].val += baseRouteMsg->getHopDelay(j);
00928 }
00929 );
00930 }
00931
00932
00933 if (((baseRouteMsg->getRoutingType() == ITERATIVE_ROUTING)
00934 || (baseRouteMsg->getRoutingType() == EXHAUSTIVE_ITERATIVE_ROUTING))
00935 || recursiveRoutingHook(thisNode, baseRouteMsg)) {
00936 handleBaseOverlayMessage(tmpMsg, baseRouteMsg->getDestKey());
00937 delete baseRouteMsg;
00938 }
00939 return;
00940 } else {
00941
00942 baseRouteMsg->setControlInfo(overlayCtrlInfo);
00943
00944
00945 if (isMalicious()) {
00946 EV << "[BaseOverlay::handleBaseOverlayMessage() @ " << thisNode.getAddress()
00947 << " (" << thisNode.getKey().toString(16) << ")]\n"
00948 << " BaseRouteMessage gets dropped because this node is malicious"
00949 << endl;
00950
00951 RECORD_STATS(numDropped++;
00952 bytesDropped += baseRouteMsg->getByteLength());
00953 delete baseRouteMsg;
00954 return;
00955 }
00956
00957 sendToKey(baseRouteMsg->getDestKey(), baseRouteMsg, 1, sourceRoute);
00958 return;
00959 }
00960 break;
00961 }
00962
00963 default:
00964 EV << "[BaseOverlay::handleBaseOverlayMessage() @ " << thisNode.getAddress()
00965 << " (" << thisNode.getKey().toString(16) << ")]\n"
00966 << " Received unknown message from UDP of type " << msg->getName()
00967 << endl;
00968 break;
00969 }
00970 }
00971
00972 void BaseOverlay::receiveChangeNotification(int category, const cPolymorphic * details)
00973 {
00974 Enter_Method_Silent();
00975 if (category == NF_OVERLAY_TRANSPORTADDRESS_CHANGED) {
00976 handleTransportAddressChangedNotification();
00977 } else if (category == NF_OVERLAY_NODE_LEAVE) {
00978 handleNodeLeaveNotification();
00979 } else if (category == NF_OVERLAY_NODE_GRACEFUL_LEAVE) {
00980 handleNodeGracefulLeaveNotification();
00981 }
00982 }
00983
00984 void BaseOverlay::handleTransportAddressChangedNotification()
00985 {
00986
00987 thisNode.setAddress(IPAddressResolver().addressOf(
00988 getParentModule()->getParentModule()).get4());
00989
00990 joinOverlay();
00991 }
00992
00993 void BaseOverlay::handleNodeLeaveNotification()
00994 {
00995
00996 }
00997
00998 void BaseOverlay::handleNodeGracefulLeaveNotification()
00999 {
01000
01001 }
01002
01003
01004 void BaseOverlay::handleAppMessage(cMessage* msg)
01005 {
01006 delete msg;
01007 }
01008
01009 void BaseOverlay::handleUDPMessage(BaseOverlayMessage* msg)
01010 {
01011 delete msg;
01012 }
01013
01014
01015 void BaseOverlay::recordOverlaySentStats(BaseOverlayMessage* msg)
01016 {
01017
01018 }
01019
01020 void BaseOverlay::setOverlayReady(bool ready)
01021 {
01022
01023 if ((ready && internalReadyState) || (!ready && !internalReadyState)) {
01024 return;
01025 }
01026
01027 internalReadyState = ready;
01028
01029 getDisplayString().setTagArg("i", 1, ready ? "" : "red");
01030 globalNodeList->setOverlayReadyIcon(getThisNode(), ready);
01031
01032 if (ready) {
01033 bootstrapList->registerBootstrapNode(thisNode);
01034 } else {
01035 bootstrapList->removeBootstrapNode(thisNode);
01036 }
01037
01038 if (globalParameters->getPrintStateToStdOut()) {
01039 std::cout << "OVERLAY STATE: " << (ready ? "READY (" : "OFFLINE (")
01040 << thisNode << ")" << std::endl;
01041 }
01042
01043 CompReadyMessage* msg = new CompReadyMessage;
01044 msg->setReady(ready);
01045 msg->setComp(OVERLAY_COMP);
01046
01047
01048 sendMessageToAllComp(msg, OVERLAY_COMP);
01049 }
01050
01051
01052
01053
01054
01055
01056
01057 void BaseOverlay::sendRouteMessage(const TransportAddress& dest,
01058 BaseRouteMessage* msg,
01059 bool ack)
01060 {
01061 OverlayCtrlInfo* ctrlInfo =
01062 dynamic_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
01063
01064
01065 if (ctrlInfo && ctrlInfo->getLastHop().getAddress() != thisNode.getAddress()) {
01066 if (msg->getStatType() == APP_DATA_STAT) {
01067 RECORD_STATS(numAppDataForwarded++;
01068 bytesAppDataForwarded += msg->getByteLength());
01069 } else if (msg->getStatType() == APP_LOOKUP_STAT){
01070 RECORD_STATS(numAppLookupForwarded++;
01071 bytesAppLookupForwarded += msg->getByteLength());
01072 } else {
01073 RECORD_STATS(numMaintenanceForwarded++;
01074 bytesMaintenanceForwarded += msg->getByteLength());
01075 }
01076 }
01077
01078 delete ctrlInfo;
01079
01080 if (msg && (dest != thisNode)) {
01081 msg->setHopCount(msg->getHopCount() + 1);
01082 }
01083 if (!ack)
01084 sendMessageToUDP(dest, msg);
01085 else {
01086 NextHopCall* nextHopCall = new NextHopCall(msg->getName());
01087 nextHopCall->setBitLength(NEXTHOPCALL_L(nextHopCall));
01088 nextHopCall->encapsulate(msg);
01089 nextHopCall->setStatType(msg->getStatType());
01090 sendUdpRpcCall(dest, nextHopCall);
01091 }
01092 }
01093 void BaseOverlay::sendMessageToUDP(const TransportAddress& dest,
01094 cPacket* msg)
01095 {
01096
01097 cPolymorphic* ctrlInfo = msg->removeControlInfo();
01098 if (ctrlInfo != NULL)
01099 delete ctrlInfo;
01100
01101
01102 if (debugOutput) {
01103 EV << "[BaseOverlay::sendMessageToUDP() @ " << thisNode.getAddress()
01104 << " (" << thisNode.getKey().toString(16) << ")]\n"
01105 << " Sending " << *msg << " to " << dest.getAddress()
01106 << endl;
01107 }
01108
01109 msg->setKind(UDP_C_DATA);
01110 UDPControlInfo* udpControlInfo = new UDPControlInfo();
01111 udpControlInfo->setSrcAddr(thisNode.getAddress());
01112 udpControlInfo->setSrcPort(thisNode.getPort());
01113 udpControlInfo->setDestAddr(dest.getAddress());
01114 udpControlInfo->setDestPort(dest.getPort());
01115 msg->setControlInfo(udpControlInfo);
01116
01117 if (dest != thisNode) {
01118 BaseOverlayMessage* baseOverlayMsg
01119 = check_and_cast<BaseOverlayMessage*>(msg);
01120
01121 if (baseOverlayMsg->getStatType() == APP_DATA_STAT) {
01122 RECORD_STATS(numAppDataSent++;
01123 bytesAppDataSent += msg->getByteLength());
01124 } else if (baseOverlayMsg->getStatType() == APP_LOOKUP_STAT){
01125 RECORD_STATS(numAppLookupSent++; bytesAppLookupSent +=
01126 msg->getByteLength());
01127 } else {
01128 RECORD_STATS(numMaintenanceSent++; bytesMaintenanceSent +=
01129 msg->getByteLength());
01130 }
01131 recordOverlaySentStats(baseOverlayMsg);
01132 } else {
01133 if (dest.getAddress() == thisNode.getAddress()) {
01134 RECORD_STATS(numInternalSent++; bytesInternalSent += msg->getByteLength());
01135 }
01136 }
01137 send(msg, "udpOut");
01138 }
01139
01140
01141
01142
01143
01144 static int pendingLookups = 0;
01145
01146 void BaseOverlay::initLookups()
01147 {
01148 lookups = LookupSet();
01149 }
01150
01151 void BaseOverlay::finishLookups()
01152 {
01153 while (lookups.size() > 0) {
01154 (*lookups.begin())->abortLookup();
01155 }
01156 lookups.clear();
01157 }
01158
01159 class SendToKeyListener : public LookupListener
01160 {
01161 private:
01162 BaseOverlay* overlay;
01163 BaseOverlayMessage* msg;
01164 GlobalStatistics* globalStatistics;
01165 public:
01166 SendToKeyListener( BaseOverlay* overlay, BaseOverlayMessage* msg ) {
01167 this->overlay = overlay;
01168 this->msg = msg;
01169 globalStatistics = overlay->globalStatistics;
01170 pendingLookups++;
01171 }
01172
01173 ~SendToKeyListener() {
01174 pendingLookups--;
01175 overlay = NULL;
01176 if (msg != NULL) {
01177 delete msg;
01178 msg = NULL;
01179 }
01180 }
01181
01182 virtual void lookupFinished(AbstractLookup *lookup) {
01183 if (dynamic_cast<BaseRouteMessage*>(msg)) {
01184 BaseRouteMessage* routeMsg = static_cast<BaseRouteMessage*>(msg);
01185 if (lookup->isValid()) {
01186 if (lookup->getResult().size()==0) {
01187 EV << "[SendToKeyListener::lookupFinished()]\n"
01188 " [ERROR] SendToKeyListener: Valid result, "
01189 "but empty array." << endl;
01190 } else {
01191 routeMsg->setHopCount(routeMsg->getHopCount()
01192 + lookup->getAccumulatedHops());
01193
01194 for (uint32_t i=0; i<lookup->getResult().size(); i++) {
01195 overlay->sendRouteMessage(lookup->getResult()[i],
01196 static_cast<BaseRouteMessage*>
01197 (routeMsg->dup()),
01198 overlay->routeMsgAcks);
01199 }
01200 }
01201 } else {
01202 EV << "[SendToKeyListener::lookupFinished()]\n"
01203 << " Lookup failed - dropping message"
01204 << endl;
01205
01206
01207
01208
01209
01210 RECORD_STATS(overlay->numDropped++;
01211 overlay->bytesDropped += routeMsg->getByteLength());
01212 }
01213 } else if (dynamic_cast<LookupCall*>(msg)) {
01214 LookupCall* call = static_cast<LookupCall*>(msg);
01215 LookupResponse* response = new LookupResponse();
01216 response->setKey(call->getKey());
01217 response->setHopCount(lookup->getAccumulatedHops());
01218 if (lookup->isValid()) {
01219 response->setIsValid(true);
01220 response->setSiblingsArraySize(lookup->getResult().size());
01221 for (uint32_t i=0; i<lookup->getResult().size(); i++) {
01222 response->setSiblings(i, lookup->getResult()[i]);
01223 }
01224 if (lookup->getResult().size() == 0) {
01225 EV << "[SendToKeyListener::lookupFinished() @ "
01226 << overlay->thisNode.getAddress()
01227 << " (" << overlay->thisNode.getKey().toString(16) << ")]\n"
01228 << " LookupCall "
01229 << call->getNonce()
01230 << " failed! (size=0)" << endl;
01231 }
01232 } else {
01233 response->setIsValid(false);
01234 EV << "[SendToKeyListener::lookupFinished() @ "
01235 << overlay->thisNode.getAddress()
01236 << " (" << overlay->thisNode.getKey().toString(16) << ")]\n"
01237 << " LookupCall "
01238 << call->getNonce()
01239 << " failed!" << endl;
01240 }
01241 overlay->sendRpcResponse(call, response);
01242 msg = NULL;
01243 } else {
01244 throw cRuntimeError("SendToKeyListener::lookupFinished(): "
01245 "Unknown message type!");
01246 }
01247 delete this;
01248 }
01249 };
01250
01251 void BaseOverlay::route(const OverlayKey& key, CompType destComp,
01252 CompType srcComp, cPacket* msg,
01253 const std::vector<TransportAddress>& sourceRoute,
01254 RoutingType routingType)
01255 {
01256 if (key.isUnspecified() &&
01257 (!sourceRoute.size() || sourceRoute[0].isUnspecified()))
01258 throw cRuntimeError("getRoute(): Key and hint unspecified!");
01259
01260
01261 BaseAppDataMessage* baseAppDataMsg =
01262 new BaseAppDataMessage("BaseAppDataMessage");
01263 baseAppDataMsg->setType(APPDATA);
01264 baseAppDataMsg->setDestComp(destComp);
01265 baseAppDataMsg->setSrcComp(srcComp);
01266 baseAppDataMsg->setBitLength(BASEAPPDATA_L(baseAppDataMsg));
01267 baseAppDataMsg->setName(msg->getName());
01268
01269 baseAppDataMsg->setStatType(APP_DATA_STAT);
01270 baseAppDataMsg->encapsulate(msg);
01271
01272
01273 if (debugOutput) {
01274 EV << "[BaseOverlay::getRoute() @ " << thisNode.getAddress()
01275 << " (" << thisNode.getKey().toString(16) << ")]\n"
01276 << " Received message from application"
01277 << endl;
01278 }
01279
01280 if (key.isUnspecified() && sourceRoute.size() <= 1) {
01281 sendMessageToUDP(sourceRoute[0], baseAppDataMsg);
01282 } else {
01283 if (internalReadyState == false) {
01284
01285 EV << "[BaseOverlay::route() @ "
01286 << overlay->thisNode.getAddress()
01287 << " (" << overlay->thisNode.getKey().toString(16) << ")]\n"
01288 << " Couldn't route application message to key "
01289 << key.toString(16)
01290 << " because the overlay module is not ready!" << endl;
01291 RECORD_STATS(numDropped++;
01292 bytesDropped += baseAppDataMsg->getByteLength());
01293 delete baseAppDataMsg;
01294 return;
01295 }
01296
01297 sendToKey(key, baseAppDataMsg, 1, sourceRoute, routingType);
01298 }
01299 }
01300
01301 bool BaseOverlay::recursiveRoutingHook(const TransportAddress& dest,
01302 BaseRouteMessage* msg)
01303 {
01304 return true;
01305 }
01306
01307 void BaseOverlay::sendToKey(const OverlayKey& key, BaseOverlayMessage* msg,
01308 int numSiblings,
01309 const std::vector<TransportAddress>& sourceRoute,
01310 RoutingType routingType)
01311 {
01312 BaseRouteMessage* routeMsg = NULL;
01313
01314 if (routingType == DEFAULT_ROUTING) routingType = defaultRoutingType;
01315
01316 if (debugOutput) {
01317 EV << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01318 << " (" << thisNode.getKey().toString(16) << ")]\n"
01319 << " Sending " << msg << " to " << key
01320 << endl;
01321 }
01322
01323 if (key.isUnspecified() &&
01324 !(sourceRoute.size() && !sourceRoute[0].isUnspecified()))
01325 throw cRuntimeError("BaseOverlay::sendToKey(): "
01326 "unspecified destination address and key!");
01327
01328 if (msg->getType() != OVERLAYROUTE) {
01329 assert(!msg->getControlInfo());
01330 routeMsg = new BaseRouteMessage("BaseRouteMessage");
01331 routeMsg->setType(OVERLAYROUTE);
01332 routeMsg->setRoutingType(routingType);
01333 routeMsg->setDestKey(key);
01334 routeMsg->setSrcNode(thisNode);
01335 routeMsg->setStatType(msg->getStatType());
01336
01337 routeMsg->setName(msg->getName());
01338 routeMsg->setBitLength(BASEROUTE_L(routeMsg));
01339 routeMsg->encapsulate(msg);
01340
01341 OverlayCtrlInfo* routeCtrlInfo = new OverlayCtrlInfo;
01342 routeCtrlInfo->setLastHop(thisNode);
01343 routeCtrlInfo->setTransportType(ROUTE_TRANSPORT);
01344 routeCtrlInfo->setRoutingType(routingType);
01345 routeMsg->setControlInfo(routeCtrlInfo);
01346
01347
01348 routeMsg->setContextPointer(NULL);
01349 } else {
01350 routeMsg = check_and_cast<BaseRouteMessage*>(msg);
01351 routingType = static_cast<RoutingType>(routeMsg->getRoutingType());
01352 }
01353
01354
01355 if (collectPerHopDelay) {
01356 routeMsg->setHopStamp(simTime());
01357 }
01358
01359 if (sourceRoute.size() && !sourceRoute[0].isUnspecified()) {
01360
01361 OverlayCtrlInfo* ctrlInfo = check_and_cast<OverlayCtrlInfo*>
01362 (routeMsg->getControlInfo());
01363 ctrlInfo->setTransportType(UDP_TRANSPORT);
01364 assert(routeMsg->getNextHopsArraySize() == 0);
01365 routeMsg->setNextHopsArraySize(sourceRoute.size());
01366 for (uint32_t i = 0; i < sourceRoute.size(); ++i)
01367 routeMsg->setNextHops(i, sourceRoute[i]);
01368 if (recursiveRoutingHook(sourceRoute[0], routeMsg)) {
01369 sendRouteMessage(sourceRoute[0], routeMsg, routeMsgAcks);
01370 }
01371 return;
01372 }
01373
01374 if ((routingType == ITERATIVE_ROUTING)
01375 || (routingType == EXHAUSTIVE_ITERATIVE_ROUTING)) {
01376
01377
01378 AbstractLookup* lookup = createLookup(routingType, routeMsg, NULL,
01379 (routeMsg->getStatType() == APP_DATA_STAT));
01380 lookup->lookup(routeMsg->getDestKey(), numSiblings, hopCountMax,
01381 0, new SendToKeyListener(this, routeMsg));
01382 } else {
01383
01384 NodeVector* nextHops = findNode(routeMsg->getDestKey(),
01385 recNumRedundantNodes,
01386 numSiblings, routeMsg);
01387
01388 if (nextHops->size() == 0) {
01389 EV << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01390 << " (" << thisNode.getKey().toString(16) << ")]\n"
01391 << " FindNode() returned NULL - dropping message"
01392 << endl;
01393
01394
01395
01396
01397
01398
01399 RECORD_STATS(numDropped++; bytesDropped += routeMsg->getByteLength());
01400 delete routeMsg;
01401 } else {
01402
01403 if (routeMsg->getHopCount() >= hopCountMax) {
01404
01405 EV << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01406 << " (" << thisNode.getKey().toString(16) << ")]\n"
01407 << " Discards " << routeMsg->getName() << " from "
01408 << routeMsg->getSrcNode().getAddress() << "\n"
01409 << " The hop count maximum has been exceeded ("
01410 << routeMsg->getHopCount() << ">="
01411 << hopCountMax << ")"
01412 << endl;
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 RECORD_STATS(numDropped++;
01424 bytesDropped += routeMsg->getByteLength());
01425 delete routeMsg;
01426 delete nextHops;
01427 return;
01428 }
01429
01430 OverlayCtrlInfo* overlayCtrlInfo =
01431 dynamic_cast<OverlayCtrlInfo*>(routeMsg->getControlInfo());
01432 assert(overlayCtrlInfo);
01433
01434
01435 NodeHandle* nextHop = NULL;
01436 bool err, isSibling;
01437 isSibling = isSiblingFor(thisNode, routeMsg->getDestKey(),
01438 numSiblings, &err);
01439
01440
01441 std::set<TransportAddress> visitedHops;
01442 for (uint32_t i = 0; i < routeMsg->getVisitedHopsArraySize(); ++i) {
01443 visitedHops.insert(routeMsg->getVisitedHops(i));
01444 }
01445
01446 for (uint32_t index = 0; nextHop == NULL && nextHops->size() > index;
01447 ++index) {
01448 nextHop = &((*nextHops)[index]);
01449
01450 if (((overlayCtrlInfo->getLastHop() == *nextHop) &&
01451 (*nextHop != thisNode)) ||
01452 (visitedHops.find(*nextHop) != visitedHops.end()) ||
01453
01454 ((*nextHop == routeMsg->getSrcNode()) &&
01455 (thisNode != routeMsg->getSrcNode())) ||
01456
01457 ((*nextHop == thisNode) && (!isSibling))) {
01458 nextHop = NULL;
01459 }
01460 }
01461
01462 if (nextHop == NULL) {
01463 if (!checkFindNode(routeMsg)) {
01464 EV << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01465 << " (" << thisNode.getKey().toString(16) << ")]\n"
01466 << " Discards " << routeMsg->getName() << " from "
01467 << routeMsg->getSrcNode().getAddress() << "\n"
01468 << " No useful nextHop found!"
01469 << endl;
01470
01471
01472
01473
01474 RECORD_STATS(numDropped++;
01475 bytesDropped += routeMsg->getByteLength());
01476 }
01477 delete routeMsg;
01478 delete nextHops;
01479 return;
01480 }
01481
01482 assert(!nextHop->isUnspecified());
01483
01484
01485 if (useCommonAPIforward &&
01486 dynamic_cast<BaseAppDataMessage*>(
01487 routeMsg->getEncapsulatedMsg()) &&
01488 routeMsg->getContextPointer() == NULL) {
01489 callForward(routeMsg->getDestKey(), routeMsg, *nextHop);
01490 delete nextHops;
01491 return;
01492 }
01493
01494 routeMsg->setContextPointer(NULL);
01495
01496
01497 if (*nextHop == thisNode) {
01498 if (isSibling && !err) {
01499
01500
01501
01502
01503
01504 delete nextHops;
01505 assert(routeMsg->getControlInfo());
01506 handleBaseOverlayMessage(routeMsg, key);
01507 return;
01508 } else {
01509 throw cRuntimeError("isSiblingsFor() is true with an "
01510 "error: Erroneous method "
01511 "isSiblingFor()!");
01512 }
01513 }
01514
01515 overlayCtrlInfo->setHopCount(routeMsg->getHopCount());
01516 if (recursiveRoutingHook(*nextHop, routeMsg)) {
01517 sendRouteMessage(*nextHop, routeMsg, routeMsgAcks);
01518 }
01519 }
01520 delete nextHops;
01521 }
01522 }
01523
01524 bool BaseOverlay::checkFindNode(BaseRouteMessage* routeMsg)
01525 {
01526 if (dynamic_cast<FindNodeCall*>(routeMsg->getEncapsulatedMsg())) {
01527 FindNodeCall* findNodeCall =
01528 static_cast<FindNodeCall*>(routeMsg->decapsulate());
01529 findNodeCall
01530 ->setControlInfo(check_and_cast<OverlayCtrlInfo*>
01531 (routeMsg->removeControlInfo()));
01532 findNodeRpc(findNodeCall);
01533 return true;
01534 }
01535 return false;
01536 }
01537
01538
01539 AbstractLookup* BaseOverlay::createLookup(RoutingType routingType,
01540 const BaseOverlayMessage* msg,
01541 const cPacket* findNodeExt,
01542 bool appLookup)
01543 {
01544 AbstractLookup* newLookup;
01545
01546 if (routingType == DEFAULT_ROUTING) {
01547 routingType = defaultRoutingType;
01548 }
01549
01550 switch (routingType) {
01551 case ITERATIVE_ROUTING:
01552 case EXHAUSTIVE_ITERATIVE_ROUTING:
01553 newLookup = new IterativeLookup(this, routingType,
01554 iterativeLookupConfig, findNodeExt,
01555 appLookup);
01556 break;
01557 case RECURSIVE_SOURCE_ROUTING:
01558 case SEMI_RECURSIVE_ROUTING:
01559 case FULL_RECURSIVE_ROUTING:
01560 newLookup = new RecursiveLookup(this, routingType,
01561 recursiveLookupConfig,
01562 appLookup);
01563 break;
01564 default:
01565 throw cRuntimeError("BaseOverlay::createLookup():"
01566 " Unknown routingType!");
01567 break;
01568 }
01569
01570 lookups.insert(newLookup);
01571 return newLookup;
01572 }
01573
01574 void BaseOverlay::removeLookup(AbstractLookup* lookup)
01575 {
01576 lookups.erase(lookup);
01577 }
01578
01579
01580 OverlayKey BaseOverlay::distance( const OverlayKey& x,
01581 const OverlayKey& y ) const
01582 {
01583 throw cRuntimeError("BaseOverlay::distance(): Not implemented!");
01584 return OverlayKey::UNSPECIFIED_KEY;
01585 }
01586
01587
01588 NodeVector* BaseOverlay::findNode(const OverlayKey& key,
01589 int numRedundantNodes,
01590 int numSiblings,
01591 BaseOverlayMessage* msg)
01592 {
01593 throw cRuntimeError("findNode: Not implemented!");
01594 return NULL;
01595 }
01596
01597
01598 void BaseOverlay::joinOverlay()
01599 {
01600
01601 return;
01602 }
01603
01604 bool BaseOverlay::handleFailedNode(const TransportAddress& failed)
01605 {
01606 return true;
01607 }
01608
01609
01610
01611
01612
01613
01614 bool BaseOverlay::internalHandleRpcCall(BaseCallMessage* msg)
01615 {
01616
01617 RPC_SWITCH_START( msg );
01618 RPC_DELEGATE( FindNode, findNodeRpc );
01619 RPC_DELEGATE( FailedNode, failedNodeRpc );
01620 RPC_DELEGATE( Lookup, lookupRpc );
01621 RPC_DELEGATE( NextHop, nextHopRpc );
01622 RPC_SWITCH_END( );
01623
01624
01625 return RPC_HANDLED || BaseRpc::internalHandleRpcCall(msg);
01626 }
01627
01628 void BaseOverlay::internalHandleRpcResponse(BaseResponseMessage* msg,
01629 cPolymorphic* context,
01630 int rpcId, simtime_t rtt)
01631 {
01632 BaseRpc::internalHandleRpcResponse(msg, context, rpcId, rtt);
01633 }
01634
01635 void BaseOverlay::internalHandleRpcTimeout(BaseCallMessage* msg,
01636 const TransportAddress& dest,
01637 cPolymorphic* context, int rpcId,
01638 const OverlayKey& destKey)
01639 {
01640 RPC_SWITCH_START( msg )
01641 RPC_ON_CALL( NextHop )
01642 {
01643 BaseRouteMessage* tempMsg
01644 = check_and_cast<BaseRouteMessage*>(msg->decapsulate());
01645
01646 if (!tempMsg->getControlInfo()) {
01647 OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo;
01648 overlayCtrlInfo->setLastHop(thisNode);
01649 overlayCtrlInfo->setHopCount(tempMsg->getHopCount());
01650 overlayCtrlInfo->setSrcNode(tempMsg->getSrcNode());
01651 overlayCtrlInfo->setRoutingType(tempMsg->getRoutingType());
01652 overlayCtrlInfo->setTransportType(UDP_TRANSPORT);
01653 tempMsg->setControlInfo(overlayCtrlInfo);
01654 }
01655
01656
01657 if (handleFailedNode(dest)) {
01658 handleBaseOverlayMessage(tempMsg, destKey);
01659 } else {
01660 RECORD_STATS(numDropped++;
01661 bytesDropped += tempMsg->getByteLength());
01662 delete tempMsg;
01663 join();
01664 }
01665 break;
01666 }
01667 RPC_SWITCH_END( )
01668
01669 BaseRpc::internalHandleRpcTimeout(msg, dest, context, rpcId, destKey);
01670 }
01671
01672 void BaseOverlay::internalSendRouteRpc(BaseRpcMessage* message,
01673 const OverlayKey& destKey,
01674 const std::vector<TransportAddress>&
01675 sourceRoute,
01676 RoutingType routingType) {
01677 FindNodeCall* findNodeCall;
01678 uint32_t numSiblings = 1;
01679 if ((findNodeCall = dynamic_cast<FindNodeCall*>(message)))
01680 numSiblings = findNodeCall->getNumSiblings();
01681
01682 sendToKey(destKey, message, numSiblings, sourceRoute, routingType);
01683 }
01684
01685 void BaseOverlay::internalSendRpcResponse(BaseCallMessage* call,
01686 BaseResponseMessage* response)
01687 {
01688 OverlayCtrlInfo* overlayCtrlInfo =
01689 check_and_cast<OverlayCtrlInfo*>(call->getControlInfo());
01690
01691 TransportType transportType = ROUTE_TRANSPORT;
01692 const TransportAddress* destNode;
01693 if (overlayCtrlInfo->getSrcNode().isUnspecified())
01694 destNode = &(overlayCtrlInfo->getLastHop());
01695 else
01696 destNode = &(overlayCtrlInfo->getSrcNode());
01697 const OverlayKey* destKey = &OverlayKey::UNSPECIFIED_KEY;
01698
01699 RoutingType routingType
01700 = static_cast<RoutingType>(overlayCtrlInfo->getRoutingType());
01701
01702 assert(overlayCtrlInfo->getTransportType() != INTERNAL_TRANSPORT);
01703
01704 if ((overlayCtrlInfo->getTransportType() == UDP_TRANSPORT) ||
01705 (routingType == SEMI_RECURSIVE_ROUTING) ||
01706 (routingType == ITERATIVE_ROUTING) ||
01707 (routingType == EXHAUSTIVE_ITERATIVE_ROUTING)) {
01708
01709 transportType = UDP_TRANSPORT;
01710 overlayCtrlInfo->setVisitedHopsArraySize(0);
01711 } else if ((static_cast<RoutingType> (overlayCtrlInfo->getRoutingType())
01712 == FULL_RECURSIVE_ROUTING)) {
01713
01714 destKey = &(overlayCtrlInfo->getSrcNode().getKey());
01715 destNode = &NodeHandle::UNSPECIFIED_NODE;
01716 }
01717
01718
01719 sendRpcResponse(transportType,
01720 static_cast<CompType>(overlayCtrlInfo->getSrcComp()),
01721 *destNode, *destKey, call, response);
01722 }
01723
01724
01725 void BaseOverlay::countFindNodeCall( const FindNodeCall* call )
01726 {
01727 RECORD_STATS(numFindNodeSent++;
01728 bytesFindNodeSent += call->getByteLength());
01729 }
01730
01731 void BaseOverlay::countFailedNodeCall( const FailedNodeCall* call )
01732 {
01733 RECORD_STATS(numFailedNodeSent++;
01734 bytesFailedNodeSent += call->getByteLength());
01735 }
01736
01737
01738 void BaseOverlay::findNodeRpc( FindNodeCall* call )
01739 {
01740
01741 if (isMalicious()) {
01742 EV << "[BaseOverlay::findNodeRpc() @ " << thisNode.getAddress()
01743 << " (" << thisNode.getKey().toString(16) << ")]\n"
01744 << " Node ignores findNodeCall because this node is malicious"
01745 << endl;
01746 delete call;
01747 return;
01748 }
01749
01750 FindNodeResponse* findNodeResponse =
01751 new FindNodeResponse("FindNodeResponse");
01752
01753 NodeVector* nextHops = findNode(call->getLookupKey(),
01754 call->getNumRedundantNodes(),
01755 call->getExhaustiveIterative() ? -1 : call->getNumSiblings(), call);
01756
01757 findNodeResponse->setClosestNodesArraySize(nextHops->size());
01758
01759 for (uint32_t i=0; i < nextHops->size(); i++) {
01760 findNodeResponse->setClosestNodes(i, (*nextHops)[i]);
01761 }
01762
01763 bool err;
01764 if (!call->getExhaustiveIterative() &&
01765 isSiblingFor(thisNode, call->getLookupKey(), call->getNumSiblings(),
01766 &err)) {
01767 findNodeResponse->setSiblings(true);
01768 }
01769
01770 #if 0
01771 if (isMalicious()) {
01772 findNodeResponse->setSiblings(true);
01773 }
01774 #endif
01775
01776 findNodeResponse->setBitLength(FINDNODERESPONSE_L(findNodeResponse));
01777
01778 if (call->hasObject("findNodeExt")) {
01779 cPacket* findNodeExt = check_and_cast<cPacket*>(call->removeObject("findNodeExt"));
01780 findNodeResponse->addObject(findNodeExt);
01781 findNodeResponse->addBitLength(findNodeExt->getBitLength());
01782 }
01783
01784 RECORD_STATS(numFindNodeResponseSent++; bytesFindNodeResponseSent +=
01785 findNodeResponse->getByteLength());
01786
01787 delete nextHops;
01788
01789 sendRpcResponse(call, findNodeResponse);
01790 }
01791
01792 void BaseOverlay::failedNodeRpc( FailedNodeCall* call )
01793 {
01794 FailedNodeResponse* failedNodeResponse =
01795 new FailedNodeResponse("FailedNodeResponse");
01796 failedNodeResponse->setTryAgain(handleFailedNode(call->getFailedNode()));
01797 failedNodeResponse->setBitLength(FAILEDNODERESPONSE_L(failedNodeResponse));
01798
01799 if (call->hasObject("findNodeExt")) {
01800 cPacket* findNodeExt = check_and_cast<cPacket*>(
01801 call->removeObject("findNodeExt"));
01802 failedNodeResponse->addObject(findNodeExt);
01803 failedNodeResponse->addBitLength(findNodeExt->getBitLength());
01804 }
01805
01806 RECORD_STATS(numFailedNodeResponseSent++; bytesFailedNodeResponseSent +=
01807 failedNodeResponse->getByteLength());
01808
01809 sendRpcResponse(call, failedNodeResponse);
01810 }
01811
01812 void BaseOverlay::lookupRpc(LookupCall* call)
01813 {
01814 int numSiblings = call->getNumSiblings();
01815
01816 if (numSiblings < 0) {
01817 numSiblings = getMaxNumSiblings();
01818 }
01819
01820 if (internalReadyState == false) {
01821
01822 EV << "[BaseOverlay::lookupRpc() @ "
01823 << overlay->thisNode.getAddress()
01824 << " (" << overlay->thisNode.getKey().toString(16) << ")]\n"
01825 << " LookupCall "
01826 << call->getNonce()
01827 << " failed, because overlay module is not ready!" << endl;
01828
01829 LookupResponse* response = new LookupResponse();
01830 response->setKey(call->getKey());
01831 response->setIsValid(false);
01832
01833 sendRpcResponse(call, response);
01834
01835 return;
01836 }
01837
01838
01839 AbstractLookup* lookup = createLookup(static_cast<RoutingType>(
01840 call->getRoutingType()), call, NULL, true);
01841 lookup->lookup(call->getKey(), numSiblings, hopCountMax,
01842 1, new SendToKeyListener( this, call ));
01843 }
01844
01845 void BaseOverlay::nextHopRpc(NextHopCall* call)
01846 {
01847 if (state != READY) {
01848
01849 delete call;
01850 return;
01851 }
01852
01853 BaseRouteMessage* routeMsg
01854 = check_and_cast<BaseRouteMessage*>(call->decapsulate());
01855
01856 OverlayCtrlInfo* overlayCtrlInfo =
01857 check_and_cast<OverlayCtrlInfo*>(call->getControlInfo()->dup());
01858 overlayCtrlInfo->setHopCount(routeMsg->getHopCount());
01859 overlayCtrlInfo->setSrcNode(routeMsg->getSrcNode());
01860 overlayCtrlInfo->setRoutingType(routeMsg->getRoutingType());
01861
01862 routeMsg->setControlInfo(overlayCtrlInfo);
01863 assert(routeMsg->getControlInfo());
01864
01865 std::string temp("ACK: [");
01866 (temp += routeMsg->getName()) += "]";
01867
01868 NextHopResponse* response
01869 = new NextHopResponse(temp.c_str());
01870 response->setBitLength(NEXTHOPRESPONSE_L(response));
01871 sendRpcResponse(call, response);
01872
01873 handleBaseOverlayMessage(routeMsg, routeMsg->getDestKey());
01874 }
01875
01876 void BaseOverlay::registerComp(CompType compType, cModule *module)
01877 {
01878 cGate *gate = NULL;
01879
01880 if (module != NULL) {
01881 gate = module->gate("direct_in");
01882 if (gate == NULL) {
01883 throw cRuntimeError("BaseOverlay::registerComp(): The module "
01884 "which tried to register has "
01885 "no direct_in gate!");
01886 }
01887 }
01888
01889 compModuleList[compType] = make_pair<cModule*, cGate*>(module, gate);
01890 }
01891
01892 cModule* BaseOverlay::getCompModule(CompType compType)
01893 {
01894 CompModuleList::iterator it = compModuleList.find(compType);
01895
01896 if (it != compModuleList.end())
01897 return it->second.first;
01898 else
01899 return NULL;
01900 }
01901
01902 cGate* BaseOverlay::getCompRpcGate(CompType compType)
01903 {
01904 CompModuleList::iterator it = compModuleList.find(compType);
01905
01906 if (it != compModuleList.end())
01907 return it->second.second;
01908 else
01909 return NULL;
01910 }
01911
01912 void BaseOverlay::sendMessageToAllComp(cMessage* msg, CompType srcComp)
01913 {
01914 for (CompModuleList::iterator it = compModuleList.begin();
01915 it != compModuleList.end(); it++) {
01916
01917
01918 if (it->first != srcComp)
01919 sendDirect((cMessage*)msg->dup(), it->second.second);
01920 }
01921
01922 delete msg;
01923 }
01924
01925 bool BaseOverlay::isInSimpleMultiOverlayHost()
01926 {
01927 return isVector() || getParentModule()->isVector();
01928 }
01929