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 == REGISTER_STAGE) {
00080         registerComp(getThisCompType(), this);
00081         return;
00082     }
00083 
00084     if (stage == MIN_STAGE_OVERLAY) {
00085         OverlayKey::setKeyLength(par("keyLength"));
00086 
00087         // find friend modules
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         // fetch some parameters
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         // we assume most overlays don't provide KBR services
00113         kbr = false;
00114 
00115         // set routing type
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         // set base lookup parameters
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; //TODO
00160 
00161         // statistics
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         // set up local nodehandle
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         // set up UDP
00251         bindToPort(localPort);
00252 
00253         // subscribe to the notification board
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         // init visualization with terminal ptr
00259         if (drawOverlayTopology)
00260             initVis(getParentModule()->getParentModule());
00261 
00262         // init rpcs
00263         initRpcs();
00264         initLookups();
00265 
00266         // statistics
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         // bootstrapList registered its gate to the overlay 0
00276         // if this is not overlay 0, we may not have the gate, so retrieve it
00277             // this assumes that the overlay is in a container module!
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 //--- General Overlay Parameters (getter and setters) --------------------
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 //--- UDP functions copied from the INET framework .----------------------
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     // TODO UDPAppBase should be ported to use UDPSocket sometime, but for now
00469     // we just manage the UDP socket by hand...
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 //--- Overlay Common API: Key-based Routing ------------------------------
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     // TODO GIA
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         // set nodeID and IP
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                 // manual configuration of nodeId in ini file
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 //--- Message Handlers ---------------------------------------------------
00690 //------------------------------------------------------------------------
00691 
00692 //private
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         // debug message
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         // records stats if message is not a UDP "self message"
00727         if (overlayCtrlInfo->getLastHop() != thisNode) {
00728             // is this from anywhere else?
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 // MAINTENANCE_STAT
00736                 RECORD_STATS(numMaintenanceReceived++;
00737                              bytesMaintenanceReceived +=
00738                                  baseOverlayMsg->getByteLength());
00739         }
00740         if (overlayCtrlInfo->getLastHop().getAddress() == thisNode.getAddress()) {
00741             // is this from the same node?
00742             RECORD_STATS(numInternalReceived++; bytesInternalReceived +=
00743                              baseOverlayMsg->getByteLength());
00744         } else overlayCtrlInfo->setHopCount(1);
00745 
00746         // process rpc calls/responses or BaseOverlayMessages
00747         if (!internalHandleMessage(msg)) {
00748             handleBaseOverlayMessage(baseOverlayMsg);
00749         }
00750     }
00751 
00752     // process timer events and rpc timeouts
00753     else if (internalHandleMessage(msg)) return;
00754 
00755     // process CommonAPIMessages from App
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             // message marked with this-pointer as already forwarded to tier1
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     // process other messages from App
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         // process rpc-messages
00842         BaseRpcMessage* rpcMsg = check_and_cast<BaseRpcMessage*>(msg);
00843 
00844         internalHandleRpcMessage(rpcMsg);
00845         return;
00846     }
00847 
00848     case APPDATA: {
00849         //TODO use route messages? here: set transport type to ROUTE for "naked"
00850         // app messages
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         // collect delay-value of completed hop
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         // set transport type
00876         overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00877 
00878         // source routing: save visited nodes, copy next hops
00879         std::vector<TransportAddress> sourceRoute;
00880         if ((baseRouteMsg->getNextHopsArraySize() > 0) ||
00881              (baseRouteMsg->getRoutingType() == RECURSIVE_SOURCE_ROUTING) ||
00882              recordRoute) {
00883             // store the TransportAddress of the sender in the visited list
00884             baseRouteMsg->setVisitedHopsArraySize(baseRouteMsg
00885                                           ->getVisitedHopsArraySize() + 1);
00886             baseRouteMsg->setVisitedHops(baseRouteMsg
00887                                           ->getVisitedHopsArraySize() - 1,
00888                                         overlayCtrlInfo->getLastHop());
00889 
00890             // remove nodes from next hops and copy them to sourceRoute
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         // decapsulate msg if node is sibling for destKey
00904         // or message is at its destination node
00905         bool err;
00906         if ((sourceRoute.size() == 0) &&
00907             (baseRouteMsg->getDestKey().isUnspecified() ||
00908              isSiblingFor(thisNode, baseRouteMsg->getDestKey(), 1, &err)
00909              /*&& !err*/)) {
00910             overlayCtrlInfo->setHopCount(baseRouteMsg->getHopCount());
00911             overlayCtrlInfo->setRoutingType(baseRouteMsg->getRoutingType());
00912 
00913             if (baseRouteMsg->getVisitedHopsArraySize() > 0) {
00914                 // recorded route available => add to srcNode
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                 // directly received (neither key routed nor source routed)
00925                 // TODO: does this happen for a BaseRouteMessage?
00926                 overlayCtrlInfo->setSrcRoute(
00927                         NodeHandle(baseRouteMsg->getSrcNode().getKey(),
00928                                    overlayCtrlInfo->getLastHop()));
00929             } else {
00930                 // route to key and no recorded route available
00931                 overlayCtrlInfo->setSrcRoute(baseRouteMsg->getSrcNode());
00932             }
00933 
00934             // copy visited nodes to control info
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             // delay between hops
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             // handle encapsulated message at destination node
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             // forward msg if this node is not responsible for the key
00979             baseRouteMsg->setControlInfo(overlayCtrlInfo);
00980 
00981             // if this node is malicious drop the message
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                 //std::cout << "malicious!" << std::endl;
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     // get new ip address
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 //virtual protected
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 //virtual protected
01052 void BaseOverlay::recordOverlaySentStats(BaseOverlayMessage* msg)
01053 {
01054     // collect statistics ...
01055 }
01056 
01057 void BaseOverlay::setOverlayReady(bool ready)
01058 {
01059     //TODO new setOverlayState(State state) function
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     // notify all registered components about new overlay state
01089     sendMessageToAllComp(msg, OVERLAY_COMP);
01090 }
01091 
01092 
01093 
01094 //------------------------------------------------------------------------
01095 //--- Messages -----------------------------------------------------------
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     // records statistics, if we forward this message
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         // TODO parameter, in recursive mode routeRetries should be 0,
01133         // in iterative mode routeRetries could be more than 0
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     // if there's still a control info attached to the message, remove it
01142     cPolymorphic* ctrlInfo = msg->removeControlInfo();
01143     if (ctrlInfo != NULL)
01144         delete ctrlInfo;
01145 
01146     // debug message
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         // record statistics, if message is not local
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 { // MAINTENANCE_STAT
01173             RECORD_STATS(numMaintenanceSent++; bytesMaintenanceSent +=
01174                          msg->getByteLength());
01175         }
01176         recordOverlaySentStats(baseOverlayMsg);
01177 
01178         if (dynamic_cast<BaseResponseMessage*>(msg) && getMeasureAuthBlock()) {
01179             // TODO: Also consider signed DhtPutMessages
01180             RECORD_STATS(bytesAuthBlockSent += ceil(AUTHBLOCK_L/8.0));
01181         }
01182     } else {
01183         if (dest.getAddress() == thisNode.getAddress()) { // to same node, but different port
01184             RECORD_STATS(numInternalSent++; bytesInternalSent += msg->getByteLength());
01185         }
01186     }
01187     send(msg, "udpOut");
01188 }
01189 
01190 //------------------------------------------------------------------------
01191 //--- Basic Routing ------------------------------------------------------
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                 //std::cout << simTime() << " "
01256                 //          << routeMsg->getSrcNode()
01257                 //          << " [SendToKeyListener::lookupFinished()]\n"
01258                 //          << "    Lookup failed - dropping message"
01259                 //          << std::endl;
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     // encapsulate in a app data message for multiplexing
01311     // to destination component
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     // debug output
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             // overlay not ready => sendToKey doesn't work yet
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         // copy the name of the inner message
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         //message marked as not already forwarded to tier1
01399         routeMsg->setContextPointer(NULL);
01400     } else {
01401         routeMsg = check_and_cast<BaseRouteMessage*>(msg);
01402         routingType = static_cast<RoutingType>(routeMsg->getRoutingType());
01403     }
01404 
01405     // set timestamp for next hop
01406     if (collectPerHopDelay) {
01407         routeMsg->setHopStamp(simTime());
01408     }
01409 
01410     if (sourceRoute.size() && !sourceRoute[0].isUnspecified()) {
01411         // send msg to nextHop if specified (used for e.g. join rpcs)
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)) { //test
01420             sendRouteMessage(sourceRoute[0], routeMsg, routeMsgAcks);
01421         }
01422         return;
01423     }
01424 
01425     if ((routingType == ITERATIVE_ROUTING)
01426         || (routingType == EXHAUSTIVE_ITERATIVE_ROUTING)
01427         ) {
01428 
01429         // create lookup and sent to key
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         // recursive routing
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             //std::cout << simTime() << " " << thisNode.getAddress() << " " << state
01446             //          << " FindNode() returned NULL - dropping message "
01447             //          << routeMsg->getName() << " from "
01448             //          << routeMsg->getSrcNode() << std::endl;
01449 
01450             // statistics
01451             RECORD_STATS(numDropped++; bytesDropped += routeMsg->getByteLength());
01452             delete routeMsg;
01453         } else {
01454             // delete message if the hop count maximum is exceeded
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                 //std::cout << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01466                 //          << " (" << thisNode.getKey().toString(16) << ")]\n"
01467                 //          << "    Discards " << routeMsg->getName() << " from "
01468                 //          << routeMsg->getSrcNode().getAddress() << "\n"
01469                 //          << "    The hop count maximum has been exceeded ("
01470                 //          << routeMsg->getHopCount() << ">="
01471                 //          << hopCountMax << ")"
01472                 //          << std::endl;
01473 
01474                 // statistics
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             // check and choose nextHop candidate
01487             NodeHandle* nextHop = NULL;
01488             bool err, isSibling;
01489             isSibling = isSiblingFor(thisNode, routeMsg->getDestKey(),
01490                                      numSiblings, &err);
01491 
01492             // if route is recorded we can do a real loop detection
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                 // loop detection
01502                 if (((overlayCtrlInfo->getLastHop() == *nextHop) &&
01503                      (*nextHop != thisNode)) ||
01504                      (visitedHops.find(*nextHop) != visitedHops.end()) ||
01505                      // do not forward msg to source node
01506                     ((*nextHop == routeMsg->getSrcNode()) &&
01507                      (thisNode != routeMsg->getSrcNode())) ||
01508                      // nextHop is thisNode, but isSiblingFor() is false
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                     //std::cout << thisNode.getAddress() << " packet from "
01523                     //          << routeMsg->getSrcNode().getAddress()
01524                     //          << " dropped: " << routeMsg
01525                     //          << " " << state << std::endl;
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             // callForward to app
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             //message marked as not already forwarded
01546             routeMsg->setContextPointer(NULL);
01547 
01548             // is this node responsible?
01549             if (*nextHop == thisNode) {
01550                 if (isSibling && !err) {
01551                     //EV << "[BaseOverlay::sendToKey() @ " << thisNode.getAddress()
01552                     //   << " (" << thisNode.getKey().toString(16) << ")]\n"
01553                     //   << "    Forwards msg for key " << routeMsg->getDestKey() "\n"
01554                     //   << "    to node " << (*nextHops)[0]
01555                     //   << endl;
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             // else forward msg if this node is not responsible for the key
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 //protected: create a lookup class
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 //virtual public
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 //protected: find closest nodes
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 //protected: join the overlay with a given nodeID
01651 void BaseOverlay::joinOverlay()
01652 {
01653 //  std::cout << "BaseOverlay::joinOverlay(): Not implemented!" << endl;
01654     return;
01655 }
01656 
01657 bool BaseOverlay::handleFailedNode(const TransportAddress& failed)
01658 {
01659     return true;
01660 }
01661 
01662 //------------------------------------------------------------------------
01663 //--- RPCs ---------------------------------------------------------------
01664 //------------------------------------------------------------------------
01665 
01666 //private
01667 bool BaseOverlay::internalHandleRpcCall(BaseCallMessage* msg)
01668 {
01669     // call rpc stubs
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     // if RPC was handled return true, else tell the parent class to handle it
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             // remove node from local routing tables
01709             // + send message again
01710             if (handleFailedNode(dest)) {
01711                 if (dest.isUnspecified()) {
01712                     // TODO: msg is resent only in recursive mode
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         // received by UDP or direct response (IR, EIR or SRR routing)
01771         transportType = UDP_TRANSPORT;
01772         overlayCtrlInfo->setVisitedHopsArraySize(0); //???
01773     } else if ((static_cast<RoutingType> (overlayCtrlInfo->getRoutingType())
01774             == FULL_RECURSIVE_ROUTING)) {
01775         // full recursive routing
01776         destKey = &(overlayCtrlInfo->getSrcNode().getKey());
01777         destNode = &NodeHandle::UNSPECIFIED_NODE;
01778     }
01779     // else: source routing -> route back over visited hops
01780 
01781     sendRpcResponse(transportType,
01782                     static_cast<CompType>(overlayCtrlInfo->getSrcComp()),
01783                     *destNode, *destKey, call, response);
01784 }
01785 
01786 //protected: statistic helpers for IterativeLookup
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 //private: rpc stub
01800 void BaseOverlay::findNodeRpc( FindNodeCall* call )
01801 {
01802     // if this node is malicious don't answer a findNodeCall
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             // was not used for evaluation
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         // overlay not ready => lookup failed
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     // create lookup and sent to key
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         //TODO EV...
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         // don't send message to the origination component
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 
Generated on Wed May 26 16:21:13 2010 for OverSim by  doxygen 1.6.3