BaseOverlay.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 //--- Initialization & finishing -----------------------------------------
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         // find friend modules
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         // fetch some parameters
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         // we assume most overlays don't provide KBR services
00102         kbr = false;
00103 
00104         // set routing type
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         // set base lookup parameters
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; //TODO
00146 
00147         // statistics
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         // set up local nodehandle
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         // set up UDP
00235         bindToPort(localPort);
00236 
00237         // subscribe to the notification board
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         // init visualization with terminal ptr
00243         if (drawOverlayTopology)
00244             initVis(getParentModule()->getParentModule());
00245 
00246         // init rpcs
00247         initRpcs();
00248         initLookups();
00249 
00250         // statistics
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         // bootstrapList registered its gate to the overlay 0
00261         // if this is not overlay 0, we may not have the gate, so retrieve it
00262             // this assumes that the overlay is in a container module!
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     // join after all components are registered
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 //--- General Overlay Parameters (getter and setters) --------------------
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 //--- UDP functions copied from the INET framework .----------------------
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     // TODO UDPAppBase should be ported to use UDPSocket sometime, but for now
00460     // we just manage the UDP socket by hand...
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 //--- Overlay Common API: Key-based Routing ------------------------------
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     // TODO GIA
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         // set nodeID and IP
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                 // manual configuration of nodeId in ini file
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 //--- Message Handlers ---------------------------------------------------
00673 //------------------------------------------------------------------------
00674 
00675 //private
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         // debug message
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         // records stats if message is not a UDP "self message"
00710         if (overlayCtrlInfo->getLastHop() != thisNode) {
00711             // is this from anywhere else?
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 // MAINTENANCE_STAT
00719                 RECORD_STATS(numMaintenanceReceived++;
00720                              bytesMaintenanceReceived +=
00721                                  baseOverlayMsg->getByteLength());
00722         }
00723         if (overlayCtrlInfo->getLastHop().getAddress() == thisNode.getAddress()) {
00724             // is this from the same node?
00725             RECORD_STATS(numInternalReceived++; bytesInternalReceived +=
00726                              baseOverlayMsg->getByteLength());
00727         } else overlayCtrlInfo->setHopCount(1);
00728 
00729         // process rpc calls/responses or BaseOverlayMessages
00730         if (!internalHandleMessage(msg)) {
00731             handleBaseOverlayMessage(baseOverlayMsg);
00732         }
00733     }
00734     // process timer events and rpc timeouts
00735     else if (internalHandleMessage(msg)) return;
00736     // process CommonAPIMessages from App
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             // message marked with this-pointer as already forwarded to tier1
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     // process other messages from App
00788     else if (msg->getArrivalGate() == appGate/*msg->arrivedOn("appIn")*/) {
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         // process rpc-messages
00807         BaseRpcMessage* rpcMsg = check_and_cast<BaseRpcMessage*>(msg);
00808 
00809         internalHandleRpcMessage(rpcMsg);
00810         return;
00811     }
00812 
00813     case APPDATA: {
00814         //TODO use route messages? here: set transport type to ROUTE for "naked"
00815         // app messages
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         // collect delay-value of completed hop
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         // set transport type
00841         overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00842 
00843         // source routing: save visited nodes, copy next hops
00844         std::vector<TransportAddress> sourceRoute;
00845         if ((baseRouteMsg->getNextHopsArraySize() > 0) ||
00846              (baseRouteMsg->getRoutingType() == RECURSIVE_SOURCE_ROUTING) ||
00847              recordRoute) {
00848             // store the TransportAddress of the sender in the visited list
00849             baseRouteMsg->setVisitedHopsArraySize(baseRouteMsg
00850                                           ->getVisitedHopsArraySize() + 1);
00851             baseRouteMsg->setVisitedHops(baseRouteMsg
00852                                           ->getVisitedHopsArraySize() - 1,
00853                                         overlayCtrlInfo->getLastHop());
00854 
00855             // remove nodes from next hops and copy them to sourceRoute
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         // decapsulate msg if node is sibling for destKey
00867         // or message is at its destination node
00868         bool err;
00869         if ((sourceRoute.size() == 0) &&
00870             (baseRouteMsg->getDestKey().isUnspecified() ||
00871              isSiblingFor(thisNode, baseRouteMsg->getDestKey(), 1, &err)
00872              /*&& !err*/)) {
00873             overlayCtrlInfo->setHopCount(baseRouteMsg->getHopCount());
00874             overlayCtrlInfo->setSrcNode(baseRouteMsg->getSrcNode());
00875             overlayCtrlInfo->setRoutingType(baseRouteMsg->getRoutingType());
00876 
00877             if (baseRouteMsg->getVisitedHopsArraySize() > 0) {
00878                 // recorded route available => add to srcNode
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                 // directly received (neither key routed nor source routed)
00889                 // TODO: does this happen for a BaseRouteMessage?
00890                 overlayCtrlInfo->setSrcRoute(
00891                         NodeHandle(baseRouteMsg->getSrcNode().getKey(),
00892                                    overlayCtrlInfo->getLastHop()));
00893             } else {
00894                 // route to key and no recorded route available
00895                 overlayCtrlInfo->setSrcRoute(baseRouteMsg->getSrcNode());
00896             }
00897 
00898             // copy visited nodes to control info
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             // delay between hops
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             // handle encapsulated message at destination node
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             // forward msg if this node is not responsible for the key
00942             baseRouteMsg->setControlInfo(overlayCtrlInfo);
00943 
00944             // if this node is malicious drop the message
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                 //std::cout << "malicious!" << std::endl;
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     // get new ip address
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 //virtual protected
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 //virtual protected
01015 void BaseOverlay::recordOverlaySentStats(BaseOverlayMessage* msg)
01016 {
01017     // collect statistics ...
01018 }
01019 
01020 void BaseOverlay::setOverlayReady(bool ready)
01021 {
01022     //TODO new setOverlayState(State state) function
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     // notify all registered components about new overlay state
01048     sendMessageToAllComp(msg, OVERLAY_COMP);
01049 }
01050 
01051 
01052 
01053 //------------------------------------------------------------------------
01054 //--- Messages -----------------------------------------------------------
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     // records statistics, if we forward this message
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     // if there's still a control info attached to the message, remove it
01097     cPolymorphic* ctrlInfo = msg->removeControlInfo();
01098     if (ctrlInfo != NULL)
01099         delete ctrlInfo;
01100 
01101     // debug message
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         // record statistics, if message is not local
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 { // MAINTENANCE_STAT
01128             RECORD_STATS(numMaintenanceSent++; bytesMaintenanceSent +=
01129                          msg->getByteLength());
01130         }
01131         recordOverlaySentStats(baseOverlayMsg);
01132     } else {
01133         if (dest.getAddress() == thisNode.getAddress()) { // to same node, but different port
01134             RECORD_STATS(numInternalSent++; bytesInternalSent += msg->getByteLength());
01135         }
01136     }
01137     send(msg, "udpOut");
01138 }
01139 
01140 //------------------------------------------------------------------------
01141 //--- Basic Routing ------------------------------------------------------
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                 //std::cout << simTime() << " "
01206                 //          << routeMsg->getSrcNode()
01207                 //          << " [SendToKeyListener::lookupFinished()]\n"
01208                 //          << "    Lookup failed - dropping message"
01209                 //          << std::endl;
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     // create base route message
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     // debug output
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             // overlay not ready => sendToKey doesn't work yet
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         // copy the name of the inner message
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         //message marked as not already forwarded to tier1
01348         routeMsg->setContextPointer(NULL);
01349     } else {
01350         routeMsg = check_and_cast<BaseRouteMessage*>(msg);
01351         routingType = static_cast<RoutingType>(routeMsg->getRoutingType());
01352     }
01353 
01354     // set timestamp for next hop
01355     if (collectPerHopDelay) {
01356         routeMsg->setHopStamp(simTime());
01357     }
01358 
01359     if (sourceRoute.size() && !sourceRoute[0].isUnspecified()) {
01360         // send msg to nextHop if specified (used for e.g. join rpcs)
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)) { //test
01369             sendRouteMessage(sourceRoute[0], routeMsg, routeMsgAcks);
01370         }
01371         return;
01372     }
01373 
01374     if ((routingType == ITERATIVE_ROUTING)
01375         || (routingType == EXHAUSTIVE_ITERATIVE_ROUTING)) {
01376 
01377         // create lookup and sent to key
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         // recursive routing
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             //std::cout << simTime() << " " << thisNode.getAddress() << " " << state
01394             //          << " FindNode() returned NULL - dropping message "
01395             //          << routeMsg->getName() << " from "
01396             //          << routeMsg->getSrcNode() << std::endl;
01397 
01398             // statistics
01399             RECORD_STATS(numDropped++; bytesDropped += routeMsg->getByteLength());
01400             delete routeMsg;
01401         } else {
01402             // delete message if the hop count maximum is exceeded
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                 //std::cout << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01414                 //          << " (" << thisNode.getKey().toString(16) << ")]\n"
01415                 //          << "    Discards " << routeMsg->getName() << " from "
01416                 //          << routeMsg->getSrcNode().getAddress() << "\n"
01417                 //          << "    The hop count maximum has been exceeded ("
01418                 //          << routeMsg->getHopCount() << ">="
01419                 //          << hopCountMax << ")"
01420                 //          << std::endl;
01421 
01422                 // statistics
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             // check and choose nextHop candidate
01435             NodeHandle* nextHop = NULL;
01436             bool err, isSibling;
01437             isSibling = isSiblingFor(thisNode, routeMsg->getDestKey(),
01438                                      numSiblings, &err);
01439 
01440             // if route is recorded we can do a real loop detection
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                 // loop detection
01450                 if (((overlayCtrlInfo->getLastHop() == *nextHop) &&
01451                      (*nextHop != thisNode)) ||
01452                      (visitedHops.find(*nextHop) != visitedHops.end()) ||
01453                      // do not forward msg to source node
01454                     ((*nextHop == routeMsg->getSrcNode()) &&
01455                      (thisNode != routeMsg->getSrcNode())) ||
01456                      // nextHop is thisNode, but isSiblingFor() is false
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                     //std::cout << thisNode.getAddress() << " packet from "
01471                     //          << routeMsg->getSrcNode().getAddress()
01472                     //          << " dropped: " << routeMsg
01473                     //          << " " << state << std::endl;
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             // callForward to app
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             //message marked as not already forwarded
01494             routeMsg->setContextPointer(NULL);
01495 
01496             // is this node responsible?
01497             if (*nextHop == thisNode) {
01498                 if (isSibling && !err) {
01499                     //EV << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01500                     //   << " (" << thisNode.getKey().toString(16) << ")]\n"
01501                     //   << "    Forwards msg for key " << routeMsg->getDestKey() "\n"
01502                     //   << "    to node " << (*nextHops)[0]
01503                     //   << endl;
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             // else forward msg if this node is not responsible for the key
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 //protected: create a lookup class
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 //virtual public
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 //protected: find closest nodes
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 //protected: join the overlay with a given nodeID
01598 void BaseOverlay::joinOverlay()
01599 {
01600 //  std::cout << "BaseOverlay::joinOverlay(): Not implemented!" << endl;
01601     return;
01602 }
01603 
01604 bool BaseOverlay::handleFailedNode(const TransportAddress& failed)
01605 {
01606     return true;
01607 }
01608 
01609 //------------------------------------------------------------------------
01610 //--- RPCs ---------------------------------------------------------------
01611 //------------------------------------------------------------------------
01612 
01613 //private
01614 bool BaseOverlay::internalHandleRpcCall(BaseCallMessage* msg)
01615 {
01616     // call rpc stubs
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     // if RPC was handled return true, else tell the parent class to handle it
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             // remove node from local routing tables
01656             // + send message again
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         // received by UDP or direct response (IR, EIR or SRR routing)
01709         transportType = UDP_TRANSPORT;
01710         overlayCtrlInfo->setVisitedHopsArraySize(0); //???
01711     } else if ((static_cast<RoutingType> (overlayCtrlInfo->getRoutingType())
01712             == FULL_RECURSIVE_ROUTING)) {
01713         // full recursive routing
01714         destKey = &(overlayCtrlInfo->getSrcNode().getKey());
01715         destNode = &NodeHandle::UNSPECIFIED_NODE;
01716     }
01717     // else: source routing -> route back over visited hops
01718 
01719     sendRpcResponse(transportType,
01720                     static_cast<CompType>(overlayCtrlInfo->getSrcComp()),
01721                     *destNode, *destKey, call, response);
01722 }
01723 
01724 //protected: statistic helpers for IterativeLookup
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 //private: rpc stub
01738 void BaseOverlay::findNodeRpc( FindNodeCall* call )
01739 {
01740     // if this node is malicious don't answer a findNodeCall
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         // overlay not ready => lookup failed
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     // create lookup and sent to key
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         //TODO EV...
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         // don't send message to the origination component
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 

Generated on Tue Sep 8 17:26:51 2009 for OverSim by  doxygen 1.5.8