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