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