Gia.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 
00024 #include <assert.h>
00025 
00026 #include <UDPControlInfo_m.h>
00027 #include <IPAddressResolver.h>
00028 #include <GlobalStatistics.h>
00029 #include <CommonMessages_m.h>
00030 #include <ExtAPIMessages_m.h>
00031 #include <InitStages.h>
00032 #include <BootstrapList.h>
00033 
00034 #include "Gia.h"
00035 
00036 
00037 Define_Module(Gia);
00038 
00039 void Gia::initializeOverlay(int stage)
00040 {
00041     // wait until IPAddressResolver initialized all interfaces and assigns addresses
00042     if(stage != MIN_STAGE_OVERLAY)
00043         return;
00044 
00045     // Get parameters from omnetpp.ini
00046     maxNeighbors = par("maxNeighbors");
00047     minNeighbors = par("minNeighbors");
00048     maxTopAdaptionInterval = par("maxTopAdaptionInterval");
00049     topAdaptionAggressiveness = par("topAdaptionAggressiveness");
00050     maxLevelOfSatisfaction = par("maxLevelOfSatisfaction");
00051     updateDelay = par("updateDelay");
00052     maxHopCount = par("maxHopCount"); //obsolete
00053     messageTimeout = par("messageTimeout");
00054     neighborTimeout = par("neighborTimeout");
00055     sendTokenTimeout = par("sendTokenTimeout");
00056     tokenWaitTime = par("tokenWaitTime");
00057     keyListDelay = par("keyListDelay");
00058     outputNodeDetails = par("outputNodeDetails");
00059     optimizeReversePath = par("optimizeReversePath");
00060 
00061     // get references on necessary modules
00062     keyListModule = check_and_cast<GiaKeyListModule*>
00063         (getParentModule()->getSubmodule("keyListModule"));
00064     neighbors = check_and_cast<GiaNeighbors*>
00065         (getParentModule()->getSubmodule("neighbors"));
00066     tokenFactory = check_and_cast<GiaTokenFactory*>
00067         (getParentModule()->getSubmodule("tokenFactory"));
00068 
00069     msgBookkeepingList = new GiaMessageBookkeeping(neighbors, messageTimeout);
00070 
00071     // clear neighbor candidate list
00072     neighCand.clear();
00073     knownNodes.clear();
00074 
00075     WATCH(thisGiaNode);
00076     WATCH(bootstrapNode);
00077     WATCH(levelOfSatisfaction);
00078 
00079     // self-messages
00080     satisfaction_timer = new cMessage("satisfaction_timer");
00081     update_timer = new cMessage("update_timer");
00082     timedoutMessages_timer = new cMessage("timedoutMessages_timer");
00083     timedoutNeighbors_timer = new cMessage("timedoutNeighbors_timer");
00084     sendKeyList_timer = new cMessage("sendKeyList_timer");
00085     sendToken_timer = new cMessage("sendToken_timer");
00086 
00087     // statistics
00088     stat_joinCount = 0;
00089     stat_joinBytesSent = 0;
00090     stat_joinREQ = 0;
00091     stat_joinREQBytesSent = 0;
00092     stat_joinRSP = 0;
00093     stat_joinRSPBytesSent = 0;
00094     stat_joinACK = 0;
00095     stat_joinACKBytesSent = 0;
00096     stat_joinDNY = 0;
00097     stat_joinDNYBytesSent = 0;
00098     stat_disconnectMessages = 0;
00099     stat_disconnectMessagesBytesSent = 0;
00100     stat_updateMessages = 0;
00101     stat_updateMessagesBytesSent = 0;
00102     stat_tokenMessages = 0;
00103     stat_tokenMessagesBytesSent = 0;
00104     stat_keyListMessages = 0;
00105     stat_keyListMessagesBytesSent = 0;
00106     stat_routeMessages = 0;
00107     stat_routeMessagesBytesSent = 0;
00108     stat_maxNeighbors = 0;
00109     stat_addedNeighbors = 0;
00110     stat_removedNeighbors = 0;
00111     stat_numSatisfactionMessages = 0;
00112     stat_sumLevelOfSatisfaction = 0.0;
00113     stat_maxLevelOfSatisfaction = 0.0;
00114 }
00115 
00116 void Gia::joinOverlay()
00117 {
00118     changeState(INIT);
00119 
00120     if (bootstrapNode.isUnspecified())
00121         changeState(READY);
00122 }
00123 
00124 void Gia::changeState(int toState)
00125 {
00126     switch (toState) {
00127     case INIT: {
00128         state = INIT;
00129 
00130         setOverlayReady(false);
00131         showOverlayNeighborArrow(thisGiaNode);
00132 
00133         // set up local nodehandle
00134         //thisGiaNode.setNodeHandle(thisNode);
00135         thisGiaNode = thisNode;
00136 
00137         callUpdate(thisNode, true);
00138 
00139         // get possible bandwidth from ppp-Module
00140         double capacity = 0;
00141 
00142         cModule* nodeModule = getParentModule()->getParentModule();
00143 
00144         if(!nodeModule->hasGate("pppg$i"))
00145             capacity += uniform(1,800000);
00146         else {
00147             // this relies on IPv4Underlay
00148                 int gateSize = nodeModule->gateSize("pppg$i");
00149             for (int i=0; i<gateSize; i++) {
00150                 cGate* currentGate = nodeModule->gate("pppg$i",i);
00151                 if (currentGate->isConnected())
00152                     capacity += check_and_cast<cDatarateChannel *>
00153                         (currentGate->getPreviousGate()->getChannel())->getDatarate()
00154                         - uniform(0,800000);
00155             }
00156         }
00157 
00158         thisGiaNode.setCapacity(capacity);
00159         //thisGiaNode.setConnectionDegree(0);
00160         //thisGiaNode.setReceivedTokens(0);
00161         //thisGiaNode.setSentTokens(0);
00162 
00163         connectionDegree = 0;
00164         receivedTokens = 0;
00165         sentTokens = 0;
00166 
00167         if (outputNodeDetails)
00168             EV << "(Gia) Node details: " << thisGiaNode << endl;
00169 
00170         // get our entry point to GIA-Overlay
00171         bootstrapNode = bootstrapList->getBootstrapNode();
00172         if(!(bootstrapNode.isUnspecified()))
00173             knownNodes.add(bootstrapNode);
00174         //else {
00175         //assert(!(thisGiaNode.getNodeHandle().isUnspecified()));
00176         //globalNodeList->registerPeer(thisGiaNode.getNodeHandle());
00177         //}
00178 
00179         // register node at TokenFactory
00180         //tokenFactory->setNode(&thisGiaNode);
00181         tokenFactory->setNeighbors(neighbors);
00182         tokenFactory->setMaxHopCount(maxHopCount);
00183 
00184         if (debugOutput)
00185             EV << "(Gia) Node " << thisGiaNode.getKey()
00186                << " (" << thisGiaNode.getAddress() << ":"
00187                << thisGiaNode.getPort() << ") with capacity: "
00188                << thisGiaNode.getCapacity()  << " entered INIT state." << endl;
00189 
00190         getParentModule()->getParentModule()->bubble("Enter INIT state.");
00191 
00192         // schedule satisfaction_timer
00193         cancelEvent(satisfaction_timer);
00194         scheduleAt(simTime(), satisfaction_timer);
00195 
00196         // schedule timedoutMessages_timer
00197         cancelEvent(timedoutMessages_timer);
00198         scheduleAt(simTime() + messageTimeout,
00199                    timedoutMessages_timer);
00200 
00201         cancelEvent(timedoutNeighbors_timer);
00202         scheduleAt(simTime() + neighborTimeout,
00203                    timedoutNeighbors_timer);
00204 
00205         cancelEvent(sendToken_timer);
00206         scheduleAt(simTime() + sendTokenTimeout,
00207                    sendToken_timer);
00208 
00209         break;
00210     }
00211     case READY:
00212         state = READY;
00213         setOverlayReady(true);
00214         break;
00215     }
00216     updateTooltip();
00217 }
00218 
00219 // void Gia::setBootstrapedIcon()
00220 // {
00221 //     if (ev.isGUI()) {
00222 //         if (state == READY) {
00223 //             getParentModule()->getParentModule()->getDisplayString().
00224 //                 setTagArg("i2", 1, "");
00225 //             getDisplayString().setTagArg("i", 1, "");
00226 //         } else {
00227 //             getParentModule()->getParentModule()->getDisplayString().
00228 //                 setTagArg("i2", 1, "red");
00229 //             getDisplayString().setTagArg("i", 1, "red");
00230 //         }
00231 //     }
00232 // }
00233 
00234 void Gia::updateTooltip()
00235 {
00236     if (ev.isGUI()) {
00237 //        if (state == READY) {
00238 //            getParentModule()->getParentModule()->getDisplayString().
00239 //                setTagArg("i2", 1, "");
00240 //            getDisplayString().setTagArg("i", 1, "");
00241 //        } else {
00242 //            getParentModule()->getParentModule()->getDisplayString().
00243 //                setTagArg("i2", 1, "red");
00244 //            getDisplayString().setTagArg("i", 1, "red");
00245 //        }
00246 
00247         std::stringstream ttString;
00248 
00249         // show our predecessor and successor in tooltip
00250         ttString << thisNode << "\n# Neighbors: "
00251                  << neighbors->getSize();
00252 
00253         getParentModule()->getParentModule()->getDisplayString().
00254             setTagArg("tt", 0, ttString.str().c_str());
00255         getParentModule()->getDisplayString().
00256             setTagArg("tt", 0, ttString.str().c_str());
00257         getDisplayString().setTagArg("tt", 0, ttString.str().c_str());
00258     }
00259 }
00260 
00261 void Gia::handleTimerEvent(cMessage* msg)
00262 {
00263     if (msg == sendToken_timer) {
00264         tokenFactory->grantToken();
00265     } else if (msg->isName("satisfaction_timer")) {
00266         // calculate level of satisfaction and select new neighbor candidate
00267 
00268         levelOfSatisfaction = calculateLevelOfSatisfaction();
00269         stat_numSatisfactionMessages++;
00270         stat_sumLevelOfSatisfaction += levelOfSatisfaction;
00271         if (levelOfSatisfaction > stat_maxLevelOfSatisfaction)
00272             stat_maxLevelOfSatisfaction = levelOfSatisfaction;
00273 
00274         // start again satisfaction_timer
00275         scheduleAt(simTime() + (maxTopAdaptionInterval *
00276                                            pow(topAdaptionAggressiveness,
00277                                                -(1 - levelOfSatisfaction))),
00278                    satisfaction_timer);
00279 
00280         // Only search a new neighbor if level of satisfaction is
00281         // under level of maxLevelOfSatisfaction
00282         if(levelOfSatisfaction < maxLevelOfSatisfaction) {
00283             if(knownNodes.getSize() == 0) {
00284                 if(neighbors->getSize() == 0 && neighCand.getSize() == 0)
00285                     knownNodes.add(globalNodeList->getBootstrapNode()/*bootstrapList->getBootstrapNode()*/);
00286                 else
00287                     return;
00288             }
00289 
00290             NodeHandle possibleNeighbor = knownNodes.getRandomCandidate();
00291 
00292             if(!(possibleNeighbor.isUnspecified()) &&
00293                thisGiaNode != possibleNeighbor &&
00294                !neighbors->contains(possibleNeighbor) &&
00295                !neighCand.contains(possibleNeighbor)) {
00296                 // try to add new neighbor
00297                 neighCand.add(possibleNeighbor);
00298                 sendMessage_JOIN_REQ(possibleNeighbor);
00299             }
00300         }
00301     } else if (msg->isName("update_timer")) {
00302         // send current capacity and degree to all neighbors
00303         for (uint32_t i=0; i<neighbors->getSize(); i++) {
00304             sendMessage_UPDATE(neighbors->get(i));
00305         }
00306     } else if (msg->isName("timedoutMessages_timer")) {
00307         // remove timedout messages
00308         msgBookkeepingList->removeTimedoutMessages();
00309         scheduleAt(simTime() + messageTimeout,
00310                    timedoutMessages_timer);
00311     } else if (msg->isName("timedoutNeighbors_timer")) {
00312         // remove timedout neighbors
00313         neighbors->removeTimedoutNodes();
00314         if (neighbors->getSize() == 0) {
00315             changeState(INIT);
00316         }
00317         cancelEvent(timedoutNeighbors_timer);
00318         scheduleAt(simTime() + neighborTimeout,
00319                    timedoutNeighbors_timer);
00320     } else if (msg->isName("sendKeyList_timer")) {
00321         if (keyList.getSize() > 0) {
00322             // send keyList to all of our neighbors
00323             for (uint32_t i=0; i<neighbors->getSize(); i++)
00324                 sendKeyListToNeighbor(neighbors->get(i));
00325         }
00326     } else {
00327         // other self-messages are notoken-self-messages
00328         // with an encapsulated message
00329         const std::string id = msg->getName();
00330         if (id.substr(0, 16) == std::string("wait-for-token: ")) {
00331                 cPacket* packet = check_and_cast<cPacket*>(msg);
00332             cMessage* decapsulatedMessage = packet->decapsulate();
00333             if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00334                 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00335                     (decapsulatedMessage);
00336                 forwardMessage(message, false);
00337             }
00338         } else if (id.substr(0, 24) == std::string("wait-for-token-fromapp: ")) {
00339             cPacket* packet = check_and_cast<cPacket*>(msg);
00340             cMessage* decapsulatedMessage = packet->decapsulate();
00341             if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00342                 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00343                     (decapsulatedMessage);
00344                 forwardMessage(message, true);
00345             }
00346         }
00347         delete msg;
00348     }
00349 }
00350 
00351 void Gia::handleUDPMessage(BaseOverlayMessage* msg)
00352 {
00353     if(debugOutput)
00354         EV << "(Gia) " << thisGiaNode << " received udp message" << endl;
00355 
00356     cPolymorphic* ctrlInfo = msg->removeControlInfo();
00357     if(ctrlInfo != NULL)
00358         delete ctrlInfo;
00359 
00360     // Parse TokenMessages
00361     if (dynamic_cast<TokenMessage*>(msg) != NULL) {
00362         TokenMessage* giaMsg = check_and_cast<TokenMessage*>(msg);
00363 
00364         // Process TOKEN-Message
00365         if ((giaMsg->getCommand() == TOKEN)) {
00366             if(debugOutput)
00367                 EV << "(Gia) Received Tokenmessage from "
00368                            << giaMsg->getSrcNode() << endl;
00369 
00370             //neighbors->setReceivedTokens(giaMsg->getSrcNode(), giaMsg->getDstTokenNr());
00371             neighbors->increaseReceivedTokens(giaMsg->getSrcNode());
00372             updateNeighborList(giaMsg);
00373         }
00374         delete msg;
00375     }
00376 
00377     // Process Route messages
00378     else if (dynamic_cast<GiaRouteMessage*>(msg) != NULL) {
00379         GiaRouteMessage* giaMsg = check_and_cast<GiaRouteMessage*>(msg);
00380         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00381                              giaMsg->getSrcDegree());
00382 
00383         if((giaMsg->getCommand() == ROUTE)) {
00384             if(debugOutput)
00385                 EV << "(Gia) Received ROUTE::IND from " << oppositeNode << endl;
00386 
00387             if(state == READY) {
00388                 //neighbors->decreaseReceivedTokens(giaMsg->getSrcNode());
00389                 updateNeighborList(giaMsg);
00390                 forwardMessage(giaMsg, false);
00391             }
00392         }
00393     }
00394 
00395     // Process KeyList-Messages
00396     else if (dynamic_cast<KeyListMessage*>(msg) != NULL) {
00397         KeyListMessage* giaMsg = check_and_cast<KeyListMessage*>(msg);
00398         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00399                              giaMsg->getSrcDegree());
00400 
00401         if (giaMsg->getCommand() == KEYLIST) {
00402             if (debugOutput)
00403                 EV << "(Gia) " << thisGiaNode
00404                    << " received KEYLIST:IND message" << endl;
00405             // update KeyList in neighborList
00406             uint32_t keyListSize = giaMsg->getKeysArraySize();
00407             GiaKeyList neighborKeyList;
00408             for (uint32_t k = 0; k < keyListSize; k++)
00409                 neighborKeyList.addKeyItem(giaMsg->getKeys(k));
00410             neighbors->setNeighborKeyList(giaMsg->getSrcNode(), neighborKeyList);
00411         }
00412         delete giaMsg;
00413     }
00414 
00415     // Process Search-Messages
00416     else if (dynamic_cast<SearchMessage*>(msg) != NULL) {
00417         SearchMessage* giaMsg = check_and_cast<SearchMessage*>(msg);
00418         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00419                              giaMsg->getSrcDegree());
00420 
00421         //neighbors->decreaseSentTokens(giaMsg->getSrcNode());
00422         updateNeighborList(giaMsg);
00423         processSearchMessage(giaMsg, false);
00424         // } else {
00425         //             EV << "(Gia) Message " << msg << " dropped!" << endl;
00426         //             RECORD_STATS(numDropped++; bytesDropped += msg->getByteLength());
00427         //             delete msg;
00428         //         }
00429     }
00430 
00431     // Process Search-Response-Messages
00432     else if (dynamic_cast<SearchResponseMessage*>(msg) != NULL) {
00433         SearchResponseMessage* responseMsg =
00434             check_and_cast<SearchResponseMessage*>(msg);
00435         forwardSearchResponseMessage(responseMsg);
00436     }
00437 
00438     // Process Gia messages
00439     else if (dynamic_cast<GiaMessage*>(msg) != NULL) {
00440         GiaMessage* giaMsg = check_and_cast<GiaMessage*>(msg);
00441 
00442         //assert(giaMsg->getSrcNode().moduleId != -1);
00443         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00444                              giaMsg->getSrcDegree());
00445 
00446         if (debugOutput)
00447             EV << "(Gia) " << thisGiaNode << " received GIA- message from "
00448                << oppositeNode << endl;
00449         updateNeighborList(giaMsg);
00450 
00451         // Process JOIN:REQ messages
00452         if (giaMsg->getCommand() == JOIN_REQUEST) {
00453             if (debugOutput)
00454                 EV << "(Gia) " << thisGiaNode
00455                    << " received JOIN:REQ message" << endl;
00456             if (acceptNode(oppositeNode, giaMsg->getSrcDegree())) {
00457                 neighCand.add(oppositeNode);
00458                 sendMessage_JOIN_RSP(oppositeNode);
00459             } else {
00460                 if (debugOutput)
00461                     EV << "(Gia) " << thisGiaNode << " denies node "
00462                        << oppositeNode << endl;
00463                 sendMessage_JOIN_DNY(oppositeNode);
00464             }
00465         }
00466 
00467         // Process JOIN:RSP messages
00468         else if (giaMsg->getCommand() == JOIN_RESPONSE) {
00469             if(debugOutput)
00470                 EV << "(Gia) " << thisGiaNode << " received JOIN:RSP message"
00471                    << endl;
00472             if(neighCand.contains(oppositeNode)) {
00473                 neighCand.remove(oppositeNode);
00474                 if(acceptNode(oppositeNode, giaMsg->getSrcDegree())) {
00475                     addNeighbor(oppositeNode, giaMsg->getSrcDegree());
00476 
00477                     GiaNeighborMessage* msg =
00478                         check_and_cast<GiaNeighborMessage*>(giaMsg);
00479                     for(uint32_t i = 0; i < msg->getNeighborsArraySize(); i++) {
00480                         GiaNode temp = msg->getNeighbors(i);
00481                         if(temp != thisGiaNode && temp != oppositeNode)
00482                             knownNodes.add(temp);
00483                     }
00484 
00485                     sendMessage_JOIN_ACK(oppositeNode);
00486                 } else {
00487                     if (debugOutput)
00488                         EV << "(Gia) " << thisGiaNode << " denies node "
00489                            << oppositeNode << endl;
00490                     sendMessage_JOIN_DNY(oppositeNode);
00491                 }
00492             }
00493         }
00494 
00495         // Process JOIN:ACK messages
00496         else if (giaMsg->getCommand() == JOIN_ACK) {
00497             if (debugOutput)
00498                 EV << "(Gia) " << thisGiaNode << " received JOIN:ACK message"
00499                    << endl;
00500             if (neighCand.contains(oppositeNode) &&
00501                 neighbors->getSize() < maxNeighbors) {
00502                 neighCand.remove(oppositeNode);
00503                 addNeighbor(oppositeNode, giaMsg->getSrcDegree());
00504 
00505                 GiaNeighborMessage* msg =
00506                     check_and_cast<GiaNeighborMessage*>(giaMsg);
00507 
00508                 for(uint32_t i = 0; i < msg->getNeighborsArraySize(); i++) {
00509                     GiaNode temp = msg->getNeighbors(i);
00510                     if(temp != thisGiaNode && temp != oppositeNode)
00511                         knownNodes.add(msg->getNeighbors(i));
00512                 }
00513             } else {
00514                 sendMessage_DISCONNECT(oppositeNode);
00515             }
00516 
00517         }
00518 
00519         // Process JOIN:DNY messages
00520         else if (giaMsg->getCommand() == JOIN_DENY) {
00521             if (debugOutput)
00522                 EV << "(Gia) " << thisGiaNode << " received JOIN:DNY message"
00523                    << endl;
00524 
00525             if (neighCand.contains(oppositeNode))
00526                 neighCand.remove(oppositeNode);
00527             knownNodes.remove(oppositeNode);
00528 
00529         }
00530 
00531 
00532         // Process DISCONNECT-Message
00533         else if (giaMsg->getCommand() == DISCONNECT) {
00534             if (debugOutput)
00535                 EV << "(Gia) " << thisGiaNode << " received DISCONNECT:IND message" << endl;
00536             removeNeighbor(giaMsg->getSrcNode());
00537         }
00538 
00539         // Process UPDATE-Message
00540         else if (giaMsg->getCommand() == UPDATE) {
00541             if (debugOutput)
00542                 EV << "(Gia) " << thisGiaNode << " received UPDATE:IND message"
00543                    << endl;
00544 
00545             neighbors->setConnectionDegree(giaMsg->getSrcNode(),
00546                                            giaMsg->getSrcDegree());
00547             //neighbors->setCapacity(giaMsg->getSrcNode(),
00548             //giaMsg->getSrcCapacity());
00549         } else {
00550             // Show unknown gia-messages
00551             if (debugOutput) {
00552                 EV << "(Gia) NODE: "<< thisGiaNode << endl
00553                    << "       Command: " << giaMsg->getCommand() << endl
00554                    << "       HopCount: " << giaMsg->getHopCount() << endl
00555                    << "       SrcKey: " << giaMsg->getSrcNode().getKey() << endl
00556                    << "       SrcIP: " << giaMsg->getSrcNode().getKey() << endl
00557                    << "       SrcPort: " << giaMsg->getSrcNode().getPort() << endl
00558                    << "       SrcCapacity: " << giaMsg->getSrcCapacity() << endl
00559                    << "       SrcDegree: " << giaMsg->getSrcDegree() << endl;
00560 
00561                 RECORD_STATS(numDropped++;bytesDropped += giaMsg->getByteLength());
00562             }
00563         }
00564         delete giaMsg;
00565     } else // PROCESS other messages than GiaMessages
00566         delete msg; // delete them all
00567 }
00568 
00569 bool Gia::acceptNode(const GiaNode& nNode, unsigned int degree)
00570 {
00571     if (neighbors->contains(nNode))
00572         return false;
00573 
00574     if (neighbors->getSize() < maxNeighbors) {
00575         // we have room for new node: accept node
00576         return true;
00577     }
00578     // we need to drop a neighbor
00579     NodeHandle dropCandidate = neighbors->getDropCandidate(nNode.getCapacity(), degree);
00580     if(!dropCandidate.isUnspecified()) {
00581         if (debugOutput)
00582             EV << "(Gia) " << thisGiaNode << " drops "
00583                << dropCandidate <<  endl;
00584         neighbors->remove(dropCandidate);
00585         sendMessage_DISCONNECT(dropCandidate);
00586         return true;
00587     }
00588     return false;
00589 }
00590 
00591 
00592 void Gia::addNeighbor(GiaNode& node, unsigned int degree)
00593 {
00594     assert(neighbors->getSize() < maxNeighbors);
00595 
00596     stat_addedNeighbors++;
00597     EV << "(Gia) " << thisGiaNode << " accepted new neighbor " << node << endl;
00598     getParentModule()->getParentModule()->bubble("New neighbor");
00599     connectionDegree = neighbors->getSize();
00600     changeState(READY);
00601     if (stat_maxNeighbors < neighbors->getSize()) {
00602         stat_maxNeighbors = neighbors->getSize();
00603     }
00604 
00605     cancelEvent(update_timer);
00606     scheduleAt(simTime() + updateDelay, update_timer);
00607 
00608     //node.setSentTokens(5);
00609     //node.setReceivedTokens(5);
00610 
00611     // send keyList to new Neighbor
00612     if (keyList.getSize() > 0)
00613         sendKeyListToNeighbor(node);
00614     neighbors->add(node, degree);
00615 
00616     showOverlayNeighborArrow(node, false,
00617                              "m=m,50,0,50,0;ls=red,1");
00618     updateTooltip();
00619 }
00620 
00621 void Gia::removeNeighbor(const GiaNode& node)
00622 {
00623     stat_removedNeighbors++;
00624 
00625     if (debugOutput)
00626         EV << "(Gia) " << thisGiaNode << " removes " << node
00627            << " from neighborlist." << endl;
00628     neighbors->remove(node);
00629 
00630     connectionDegree = neighbors->getSize();
00631 
00632     if (neighbors->getSize() == 0) {
00633         changeState(INIT);
00634     }
00635 
00636     deleteOverlayNeighborArrow(node);
00637     updateTooltip();
00638 
00639     cancelEvent(update_timer);
00640     scheduleAt(simTime() + updateDelay, update_timer);
00641 }
00642 
00643 double Gia::calculateLevelOfSatisfaction()
00644 {
00645     uint32_t neighborsCount = neighbors->getSize();
00646     if(neighborsCount < minNeighbors)
00647         return 0.0;
00648 
00649     double total = 0.0;
00650     double levelOfSatisfaction = 0.0;
00651 
00652     for (uint32_t i=0; i < neighborsCount; i++)
00653         total += neighbors->get(i).getCapacity() / neighborsCount;
00654 
00655     assert(thisGiaNode.getCapacity() != 0);
00656     levelOfSatisfaction = total / thisGiaNode.getCapacity();
00657 
00658     if ((levelOfSatisfaction > 1.0) || (neighborsCount >= maxNeighbors))
00659         return 1.0;
00660     return levelOfSatisfaction;
00661 }
00662 
00663 
00664 void Gia::sendMessage_JOIN_REQ(const NodeHandle& dst)
00665 {
00666     // send JOIN:REQ message
00667     GiaMessage* msg = new GiaMessage("JOIN_REQ");
00668     msg->setCommand(JOIN_REQUEST);
00669     msg->setSrcNode(thisGiaNode);
00670     msg->setSrcCapacity(thisGiaNode.getCapacity());
00671     msg->setSrcDegree(connectionDegree);
00672     msg->setBitLength(GIA_L(msg));
00673 
00674     stat_joinCount += 1;
00675     stat_joinBytesSent += msg->getByteLength();
00676     stat_joinREQ += 1;
00677     stat_joinREQBytesSent += msg->getByteLength();
00678 
00679     sendMessageToUDP(dst, msg);
00680 }
00681 
00682 void Gia::sendMessage_JOIN_RSP(const NodeHandle& dst)
00683 {
00684     // send JOIN:RSP message
00685     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_RSP");
00686     msg->setCommand(JOIN_RESPONSE);
00687     msg->setSrcNode(thisGiaNode);
00688     msg->setSrcCapacity(thisGiaNode.getCapacity());
00689     msg->setSrcDegree(connectionDegree);
00690 
00691     msg->setNeighborsArraySize(neighbors->getSize());
00692     //TODO: add parameter maxSendNeighbors
00693     for(uint32_t i = 0; i < neighbors->getSize(); i++)
00694         msg->setNeighbors(i, neighbors->get(i));
00695 
00696     msg->setBitLength(GIANEIGHBOR_L(msg));
00697 
00698     stat_joinCount += 1;
00699     stat_joinBytesSent += msg->getByteLength();
00700     stat_joinRSP += 1;
00701     stat_joinRSPBytesSent += msg->getByteLength();
00702 
00703     sendMessageToUDP(dst, msg);
00704 }
00705 
00706 void Gia::sendMessage_JOIN_ACK(const NodeHandle& dst)
00707 {
00708     // send JOIN:ACK message
00709     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_ACK");
00710     msg->setCommand(JOIN_ACK);
00711     msg->setSrcNode(thisGiaNode);
00712     msg->setSrcCapacity(thisGiaNode.getCapacity());
00713     msg->setSrcDegree(connectionDegree);
00714 
00715     msg->setNeighborsArraySize(neighbors->getSize());
00716     //TODO: add parameter maxSendNeighbors
00717     for(uint32_t i = 0; i < neighbors->getSize(); i++)
00718         msg->setNeighbors(i, neighbors->get(i));
00719 
00720     msg->setBitLength(GIANEIGHBOR_L(msg));
00721 
00722     stat_joinCount += 1;
00723     stat_joinBytesSent += msg->getByteLength();
00724     stat_joinACK += 1;
00725     stat_joinACKBytesSent += msg->getByteLength();
00726 
00727     sendMessageToUDP(dst, msg);
00728 }
00729 
00730 void Gia::sendMessage_JOIN_DNY(const NodeHandle& dst)
00731 {
00732     // send JOIN:DNY message
00733     GiaMessage* msg = new GiaMessage("JOIN_DENY");
00734     msg->setCommand(JOIN_DENY);
00735     msg->setSrcNode(thisGiaNode);
00736     msg->setSrcCapacity(thisGiaNode.getCapacity());
00737     msg->setSrcDegree(connectionDegree);
00738     msg->setBitLength(GIA_L(msg));
00739 
00740     stat_joinCount += 1;
00741     stat_joinBytesSent += msg->getByteLength();
00742     stat_joinDNY += 1;
00743     stat_joinDNYBytesSent += msg->getByteLength();
00744 
00745     sendMessageToUDP(dst, msg);
00746 }
00747 
00748 void Gia::sendMessage_DISCONNECT(const NodeHandle& dst)
00749 {
00750     // send DISCONNECT:IND message
00751     GiaMessage* msg = new GiaMessage("DISCONNECT");
00752     msg->setCommand(DISCONNECT);
00753     msg->setSrcNode(thisGiaNode);
00754     msg->setSrcCapacity(thisGiaNode.getCapacity());
00755     msg->setSrcDegree(connectionDegree);
00756     msg->setBitLength(GIA_L(msg));
00757 
00758     stat_disconnectMessagesBytesSent += msg->getByteLength();
00759     stat_disconnectMessages += 1;
00760 
00761     sendMessageToUDP(dst, msg);
00762 }
00763 
00764 void Gia::sendMessage_UPDATE(const NodeHandle& dst)
00765 {
00766     // send UPDATE:IND message
00767     GiaMessage* msg = new GiaMessage("UPDATE");
00768     msg->setCommand(UPDATE);
00769     msg->setSrcNode(thisGiaNode);
00770     msg->setSrcCapacity(thisGiaNode.getCapacity());
00771     msg->setSrcDegree(connectionDegree);
00772     msg->setBitLength(GIA_L(msg));
00773 
00774     stat_updateMessagesBytesSent += msg->getByteLength();
00775     stat_updateMessages += 1;
00776 
00777     sendMessageToUDP(dst, msg);
00778 }
00779 
00780 void Gia::sendKeyListToNeighbor(const NodeHandle& dst)
00781 {
00782     // send KEYLIST:IND message
00783     KeyListMessage* msg = new KeyListMessage("KEYLIST");
00784     msg->setCommand(KEYLIST);
00785     msg->setSrcNode(thisGiaNode);
00786     msg->setSrcCapacity(thisGiaNode.getCapacity());
00787     msg->setSrcDegree(connectionDegree);
00788 
00789     msg->setKeysArraySize(keyList.getSize());
00790     for (uint32_t i=0; i<keyList.getSize(); i++)
00791         msg->setKeys(i, keyList.get(i));
00792 
00793     msg->setBitLength(KEYLIST_L(msg));
00794 
00795     stat_keyListMessagesBytesSent += msg->getByteLength();
00796     stat_keyListMessages += 1;
00797 
00798     sendMessageToUDP(dst, msg);
00799 }
00800 
00801 void Gia::sendToken(const GiaNode& dst)
00802 {
00803     TokenMessage* tokenMsg = new TokenMessage("TOKEN");
00804     tokenMsg->setCommand(TOKEN);
00805     tokenMsg->setHopCount(maxHopCount);
00806     tokenMsg->setSrcNode(thisGiaNode);
00807     tokenMsg->setSrcCapacity(thisGiaNode.getCapacity());
00808     tokenMsg->setSrcDegree(connectionDegree);
00809     tokenMsg->setSrcTokenNr(0/*dst.getReceivedTokens()*/);//???
00810     tokenMsg->setDstTokenNr(/*dst.getSentTokens()+*/1);
00811     tokenMsg->setBitLength(TOKEN_L(tokenMsg));
00812 
00813     stat_tokenMessagesBytesSent += tokenMsg->getByteLength();
00814     stat_tokenMessages += 1;
00815 
00816     sendMessageToUDP(dst, tokenMsg);
00817 }
00818 
00819 void Gia::updateNeighborList(GiaMessage* msg)
00820 {
00821     if(neighbors->contains(msg->getSrcNode().getKey())) {
00822         neighbors->setConnectionDegree(msg->getSrcNode(),msg->getSrcDegree());
00823         //neighbors->setCapacity(msg->getSrcNode(), msg->getSrcCapacity());
00824         neighbors->updateTimestamp(msg->getSrcNode());
00825     }
00826 }
00827 
00828 void Gia::forwardSearchResponseMessage(SearchResponseMessage* responseMsg)
00829 {
00830     if (responseMsg->getHopCount() != 0) {
00831         uint32_t reversePathArraySize = responseMsg->getReversePathArraySize();
00832 
00833         // reached node which started search?
00834         if (reversePathArraySize == 0) {
00835             deliverSearchResult(responseMsg);
00836         }
00837         // forward message to next node in reverse path list
00838         else {
00839             NodeHandle targetNode = neighbors->get
00840                 (responseMsg->getReversePath(
00841                                              reversePathArraySize-1));
00842 
00843             if(!(targetNode.isUnspecified())) {
00844                 responseMsg->setDestKey(targetNode.getKey());
00845                 responseMsg->setReversePathArraySize(reversePathArraySize-1);
00846                 for (uint32_t i=0; i<reversePathArraySize-1; i++)
00847                     responseMsg->setReversePath(i, responseMsg->getReversePath(i));
00848                 responseMsg->setBitLength(responseMsg->getBitLength() - KEY_L);
00849 
00850                 stat_routeMessagesBytesSent += responseMsg->getByteLength();
00851                 stat_routeMessages += 1;
00852 
00853                 if(responseMsg->getHopCount() > 0)
00854                     RECORD_STATS(numAppDataForwarded++; bytesAppDataForwarded +=
00855                                  responseMsg->getByteLength());
00856 
00857                 sendMessageToUDP(targetNode, responseMsg);
00858             } else {
00859                 EV << "(Gia) wrong reverse path in " << *responseMsg
00860                    << " ... deleted!" << endl;
00861                 RECORD_STATS(numDropped++;
00862                              bytesDropped += responseMsg->getByteLength());
00863                 delete responseMsg;
00864             }
00865         }
00866     }
00867     // max hopcount reached. delete message
00868     else
00869         delete responseMsg;
00870 }
00871 
00872 void Gia::forwardMessage(GiaIDMessage* msg , bool fromApplication)
00873 {
00874     if (msg->getHopCount() == 0) {
00875         // Max-Hopcount reached. Discard message
00876         if (!fromApplication)
00877             tokenFactory->grantToken();
00878         RECORD_STATS(numDropped++; bytesDropped += msg->getByteLength());
00879         delete msg;
00880     } else {
00881         // local delivery?
00882         if (msg->getDestKey() == thisGiaNode.getKey()) {
00883             if(!fromApplication)
00884                 tokenFactory->grantToken();
00885 
00886             if(debugOutput)
00887                 EV << "(Gia) Deliver messsage " << msg
00888                    << " to application at " << thisGiaNode << endl;
00889 
00890             OverlayCtrlInfo* overlayCtrlInfo =
00891                 new OverlayCtrlInfo();
00892 
00893             overlayCtrlInfo->setHopCount(msg->getHopCount());
00894             overlayCtrlInfo->setSrcNode(msg->getSrcNode());
00895             overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00896             overlayCtrlInfo->setDestComp(TIER1_COMP); // workaround
00897             overlayCtrlInfo->setSrcComp(TIER1_COMP);
00898 
00899             msg->setControlInfo(overlayCtrlInfo);
00900             callDeliver(msg, msg->getDestKey());
00901         } else {
00902             // forward message to next hop
00903 
00904             // do we know the destination-node?
00905             if (neighbors->contains(msg->getDestKey())) {
00906                 // yes, destination-Node is our neighbor
00907                 NodeHandle targetNode = neighbors->get(msg->getDestKey());
00908                 GiaNeighborInfo* targetInfo= neighbors->get(targetNode);
00909 
00910                 if (targetInfo->receivedTokens == 0) {
00911                     // wait for free token
00912                     if (debugOutput)
00913                         EV << "(Gia) No free Node, wait for free token" << endl;
00914 
00915                     //bad code
00916                     std::string id;
00917                     if (!fromApplication)
00918                         id = "wait-for-token: " + msg->getID().toString();
00919                     else
00920                         id = "wait-for-token-fromapp: " +
00921                             msg->getID().toString();
00922                     cPacket* wait_timer = new cPacket(id.c_str());
00923                     wait_timer->encapsulate(msg);
00924                     scheduleAt(simTime() + tokenWaitTime,wait_timer);
00925                     return;
00926                 } else {
00927                     // decrease nextHop-tokencount
00928                     neighbors->decreaseReceivedTokens(targetNode);
00929                     //targetInfo->receivedTokens = targetInfo->receivedTokens - 1;
00930 
00931                     // forward msg to nextHop
00932                     msg->setHopCount(msg->getHopCount()-1);
00933                     msg->setSrcNode(thisGiaNode);
00934                     msg->setSrcCapacity(thisGiaNode.getCapacity());
00935                     msg->setSrcDegree(connectionDegree);
00936                     if (debugOutput)
00937                         EV << "(Gia) Forwarding message " << msg
00938                            << " to neighbor " << targetNode << endl;
00939                     if (!fromApplication)
00940                         tokenFactory->grantToken();
00941 
00942                     stat_routeMessagesBytesSent += msg->getByteLength();
00943                     stat_routeMessages += 1;
00944 
00945                     if(msg->getHopCount() > 0)
00946                         RECORD_STATS(numAppDataForwarded++; bytesAppDataForwarded +=
00947                                      msg->getByteLength());
00948 
00949                     sendMessageToUDP(targetNode, msg);
00950                 }
00951             } else {
00952                 // no => pick node with at least one token and highest capacity
00953                 if (!msgBookkeepingList->contains(msg))
00954                     msgBookkeepingList->addMessage(msg);
00955                 NodeHandle nextHop = msgBookkeepingList->getNextHop(msg);
00956                 // do we have a neighbor who send us a token?
00957                 if(nextHop.isUnspecified()) {
00958                     // wait for free token
00959                     if (debugOutput)
00960                         EV << "(Gia) No free Node, wait for free token" << endl;
00961                     std::string id;
00962                     if (!fromApplication)
00963                         id = "wait-for-token: " + msg->getID().toString();
00964                     else
00965                         id = "wait-for-token-fromapp: " +
00966                             msg->getID().toString();
00967                     cPacket* wait_timer = new cPacket(id.c_str());
00968                     wait_timer->encapsulate(msg);
00969                     scheduleAt(simTime() + tokenWaitTime,wait_timer);
00970                     return;
00971                 } else {
00972                     GiaNeighborInfo* nextHopInfo = neighbors->get(nextHop);
00973                     if(nextHopInfo == NULL) {
00974                         delete msg;
00975                         return; //???
00976                     }
00977                     // decrease nextHop-tokencount
00978                     neighbors->decreaseReceivedTokens(nextHop);
00979                     //nextHopInfo->receivedTokens--;
00980 
00981                     // forward msg to nextHop
00982                     msg->setHopCount(msg->getHopCount()-1);
00983                     msg->setSrcNode(thisGiaNode);
00984                     msg->setSrcCapacity(thisGiaNode.getCapacity());
00985                     msg->setSrcDegree(connectionDegree);
00986                     if (debugOutput)
00987                         EV << "(Gia) Forwarding message " << msg
00988                            << " to " << nextHop << endl;
00989                     if (!fromApplication)
00990                         tokenFactory->grantToken();
00991 
00992                     stat_routeMessagesBytesSent += msg->getByteLength();
00993                     stat_routeMessages += 1;
00994 
00995                     if(msg->getHopCount() > 0)
00996                         RECORD_STATS(numAppDataForwarded++; bytesAppDataForwarded +=
00997                                      msg->getByteLength());
00998 
00999                     sendMessageToUDP(nextHop, msg);
01000                 }
01001             }
01002         }
01003     }
01004 }
01005 
01006 void Gia::getRoute(const OverlayKey& key, CompType destComp,
01007                 CompType srcComp, cPacket* msg,
01008                 const std::vector<TransportAddress>& sourceRoute,
01009                 RoutingType routingType)
01010 {
01011     if ((destComp != TIER1_COMP) || (srcComp != TIER1_COMP)) {
01012         throw cRuntimeError("Gia::getRoute(): Works currently "
01013                              "only with srcComp=destComp=TIER1_COMP!");
01014     }
01015 
01016     if (state == READY) {
01017         GiaRouteMessage* routeMsg = new GiaRouteMessage("ROUTE");
01018         routeMsg->setStatType(APP_DATA_STAT);
01019         routeMsg->setCommand(ROUTE);
01020         routeMsg->setHopCount(maxHopCount);
01021         routeMsg->setDestKey(key);
01022         routeMsg->setSrcNode(thisGiaNode);
01023         routeMsg->setSrcCapacity(thisGiaNode.getCapacity());
01024         routeMsg->setSrcDegree(connectionDegree);
01025         routeMsg->setOriginatorKey(thisGiaNode.getKey());
01026         routeMsg->setOriginatorIP(thisGiaNode.getAddress());
01027         routeMsg->setOriginatorPort(thisGiaNode.getPort());
01028         routeMsg->setID(OverlayKey::random());
01029         routeMsg->setBitLength(GIAROUTE_L(routeMsg));
01030         routeMsg->encapsulate(msg);
01031 
01032 
01033         forwardMessage(routeMsg, true);
01034     } else {
01035         RECORD_STATS(numDropped++; bytesDropped += msg->getByteLength());
01036         delete msg;
01037     }
01038 }
01039 
01040 void Gia::handleAppMessage(cMessage* msg)
01041 {
01042     // do we receive a keylist?
01043     if (dynamic_cast<GIAput*>(msg) != NULL) {
01044         GIAput* putMsg = check_and_cast<GIAput*>(msg);
01045         uint32_t keyListSize = putMsg->getKeysArraySize();
01046         for (uint32_t k=0; k<keyListSize; k++)
01047             keyList.addKeyItem(putMsg->getKeys(k));
01048 
01049         // actualize vector in KeyListModule
01050         keyListModule->setKeyListVector(keyList.getVector());
01051 
01052         scheduleAt(simTime() + keyListDelay, sendKeyList_timer);
01053 
01054         delete putMsg;
01055     } else if (dynamic_cast<GIAsearch*>(msg) != NULL) {
01056         if (state == READY) {
01057             GIAsearch* getMsg = check_and_cast<GIAsearch*>(msg);
01058             SearchMessage* searchMsg = new SearchMessage("SEARCH");
01059             searchMsg->setCommand(SEARCH);
01060             searchMsg->setStatType(APP_DATA_STAT);
01061             searchMsg->setHopCount(maxHopCount);
01062             searchMsg->setDestKey(getMsg->getSearchKey());
01063             searchMsg->setSrcNode(thisGiaNode);
01064             searchMsg->setSrcCapacity(thisGiaNode.getCapacity());
01065             searchMsg->setSrcDegree(connectionDegree);
01066             searchMsg->setSearchKey(getMsg->getSearchKey());
01067             searchMsg->setMaxResponses(getMsg->getMaxResponses());
01068             searchMsg->setReversePathArraySize(0);
01069             searchMsg->setID(OverlayKey::random());
01070             searchMsg->setBitLength(SEARCH_L(searchMsg));
01071 
01072             processSearchMessage(searchMsg, true);
01073 
01074             delete getMsg;
01075         } else
01076             delete msg;
01077     } else {
01078         delete msg;
01079         EV << "(Gia) unkown message from app deleted!" << endl;
01080     }
01081 }
01082 
01083 
01084 void Gia::sendSearchResponseMessage(const GiaNode& srcNode, SearchMessage* msg)
01085 {
01086     // does SearchMessage->foundNode[] already contain this node
01087     uint32_t foundNodeArraySize = msg->getFoundNodeArraySize();
01088     bool containsNode = false;
01089     for (uint32_t i=0; i<foundNodeArraySize; i++)
01090         if (srcNode.getKey() == msg->getFoundNode(i))
01091             containsNode = true;
01092 
01093     if (!containsNode && msg->getMaxResponses() > 0) {
01094         // add this node to SearchMessage->foundNode[]
01095         msg->setFoundNodeArraySize(foundNodeArraySize+1);
01096         msg->setFoundNode(foundNodeArraySize, srcNode.getKey());
01097 
01098         // decrease SearchMessage->maxResponses
01099         msg->setMaxResponses(msg->getMaxResponses()-1);
01100 
01101         // get first node in reverse-path
01102         uint32_t reversePathArraySize = msg->getReversePathArraySize();
01103 
01104         if (reversePathArraySize == 0) {
01105             // we have the key
01106             // deliver response to application
01107             SearchResponseMessage* responseMsg =
01108                 new SearchResponseMessage("ANSWER");
01109             responseMsg->setCommand(ANSWER);
01110             responseMsg->setStatType(APP_DATA_STAT);
01111             responseMsg->setHopCount(maxHopCount);
01112             responseMsg->setSrcNode(thisGiaNode);
01113             responseMsg->setSrcCapacity(thisGiaNode.getCapacity());
01114             responseMsg->setSrcDegree(connectionDegree);
01115             responseMsg->setSearchKey(msg->getSearchKey());
01116             responseMsg->setFoundNode(srcNode);
01117             responseMsg->setID(OverlayKey::random());
01118             responseMsg->setSearchHopCount(0);
01119 
01120             responseMsg->setBitLength(SEARCHRESPONSE_L(responseMsg));
01121 
01122             deliverSearchResult(responseMsg);
01123         } else {
01124             uint32_t reversePathArraySize(msg->getReversePathArraySize());
01125             SearchResponseMessage* responseMsg =
01126                 new SearchResponseMessage("ANSWER");
01127             responseMsg->setCommand(ANSWER);
01128             responseMsg->setHopCount(maxHopCount);
01129             responseMsg->setSrcNode(srcNode);
01130             responseMsg->setSrcCapacity(srcNode.getCapacity());
01131             responseMsg->setSrcDegree(connectionDegree);
01132             responseMsg->setSearchKey(msg->getSearchKey());
01133             responseMsg->setFoundNode(srcNode);
01134             responseMsg->setReversePathArraySize(reversePathArraySize);
01135             for (uint32_t i=0; i<reversePathArraySize; i++)
01136                 responseMsg->setReversePath(i, msg->getReversePath(i));
01137             responseMsg->setID(OverlayKey::random());
01138             responseMsg->setSearchHopCount(reversePathArraySize);
01139             responseMsg->setBitLength(SEARCHRESPONSE_L(responseMsg));
01140 
01141             forwardSearchResponseMessage(responseMsg);
01142         }
01143     }
01144 }
01145 
01146 
01147 void Gia::processSearchMessage(SearchMessage* msg, bool fromApplication)
01148 {
01149     OverlayKey searchKey = msg->getSearchKey();
01150 
01151     if (keyList.contains(searchKey)) {
01152         // this node contains search key
01153         sendSearchResponseMessage(thisGiaNode, msg);
01154     }
01155 
01156     // check if neighbors contain search key
01157     for (uint32_t i = 0; i < neighbors->getSize(); i++) {
01158         GiaKeyList* keyList = neighbors->getNeighborKeyList(neighbors->get(i));
01159         if (keyList->contains(searchKey))
01160             sendSearchResponseMessage(neighbors->get(i), msg);
01161     }
01162 
01163     // forward search-message to next hop
01164     if (msg->getMaxResponses() > 0) {
01165         // actualize reverse path
01166         uint32_t reversePathSize = msg->getReversePathArraySize();
01167 
01168         if (optimizeReversePath)
01169             for (uint32_t i=0; i<reversePathSize; i++) {
01170                 if (msg->getReversePath(i) == thisGiaNode.getKey()) {
01171                     // Our node already in ReversePath.
01172                     // Delete successor nodes from ReversePath
01173                     msg->setBitLength(msg->getBitLength() - (reversePathSize - i)*KEY_L);
01174                     reversePathSize = i; // set new array size
01175                     break;
01176                 }
01177             }
01178 
01179         msg->setReversePathArraySize(reversePathSize+1);
01180         msg->setReversePath(reversePathSize, thisGiaNode.getKey());
01181         msg->setBitLength(msg->getBitLength() + KEY_L);
01182 
01183         forwardMessage(msg, fromApplication);
01184     } else {
01185         tokenFactory->grantToken();
01186         delete msg;
01187     }
01188 }
01189 
01190 void Gia::deliverSearchResult(SearchResponseMessage* msg)
01191 {
01192     OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo();
01193     overlayCtrlInfo->setHopCount(msg->getSearchHopCount());
01194     overlayCtrlInfo->setSrcNode(msg->getSrcNode());
01195     overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
01196 
01197     GIAanswer* deliverMsg = new GIAanswer("GIA-Answer");
01198     deliverMsg->setCommand(GIA_ANSWER);
01199     deliverMsg->setControlInfo(overlayCtrlInfo);
01200     deliverMsg->setSearchKey(msg->getSearchKey());
01201     deliverMsg->setNode(msg->getFoundNode());
01202     deliverMsg->setBitLength(GIAGETRSP_L(msg));
01203 
01204     send(deliverMsg, "appOut");
01205     if (debugOutput)
01206         EV << "(Gia) Deliver search response " << msg
01207            << " to application at " << thisGiaNode << endl;
01208 
01209     delete msg;
01210 }
01211 
01212 void Gia::finishOverlay()
01213 {
01214     // statistics
01215 
01216     globalStatistics->addStdDev("GIA: JOIN-Messages Count", stat_joinCount);
01217     globalStatistics->addStdDev("GIA: JOIN Bytes sent", stat_joinBytesSent);
01218     globalStatistics->addStdDev("GIA: JOIN::REQ Messages", stat_joinREQ);
01219     globalStatistics->addStdDev("GIA: JOIN::REQ Bytes sent", stat_joinREQBytesSent);
01220     globalStatistics->addStdDev("GIA: JOIN::RSP Messages", stat_joinRSP);
01221     globalStatistics->addStdDev("GIA: JOIN::RSP Bytes sent", stat_joinRSPBytesSent);
01222     globalStatistics->addStdDev("GIA: JOIN::ACK Messages", stat_joinACK);
01223     globalStatistics->addStdDev("GIA: JOIN::ACK Bytes sent", stat_joinACKBytesSent);
01224     globalStatistics->addStdDev("GIA: JOIN::DNY Messages", stat_joinDNY);
01225     globalStatistics->addStdDev("GIA: JOIN::DNY Bytes sent", stat_joinDNYBytesSent);
01226     globalStatistics->addStdDev("GIA: DISCONNECT:IND Messages", stat_disconnectMessages);
01227     globalStatistics->addStdDev("GIA: DISCONNECT:IND Bytes sent",
01228                                 stat_disconnectMessagesBytesSent);
01229     globalStatistics->addStdDev("GIA: UPDATE:IND Messages", stat_updateMessages);
01230     globalStatistics->addStdDev("GIA: UPDATE:IND Bytes sent", stat_updateMessagesBytesSent);
01231     globalStatistics->addStdDev("GIA: TOKEN:IND Messages", stat_tokenMessages);
01232     globalStatistics->addStdDev("GIA: TOKEN:IND Bytes sent", stat_tokenMessagesBytesSent);
01233     globalStatistics->addStdDev("GIA: KEYLIST:IND Messages", stat_keyListMessages);
01234     globalStatistics->addStdDev("GIA: KEYLIST:IND Bytes sent", stat_keyListMessagesBytesSent);
01235     globalStatistics->addStdDev("GIA: ROUTE:IND Messages", stat_routeMessages);
01236     globalStatistics->addStdDev("GIA: ROUTE:IND Bytes sent", stat_routeMessagesBytesSent);
01237     globalStatistics->addStdDev("GIA: Neighbors max", stat_maxNeighbors);
01238     globalStatistics->addStdDev("GIA: Neighbors added", stat_addedNeighbors);
01239     globalStatistics->addStdDev("GIA: Neighbors removed", stat_removedNeighbors);
01240     globalStatistics->addStdDev("GIA: Level of satisfaction messages ",
01241                                 stat_numSatisfactionMessages);
01242     globalStatistics->addStdDev("GIA: Level of satisfaction max ",stat_maxLevelOfSatisfaction);
01243     globalStatistics->addStdDev("GIA: Level of satisfaction avg ",
01244                                 stat_sumLevelOfSatisfaction / stat_numSatisfactionMessages);
01245     bootstrapList->removeBootstrapNode(thisGiaNode);
01246 }
01247 
01248 Gia::~Gia()
01249 {
01250     cancelAndDelete(satisfaction_timer);
01251     cancelAndDelete(update_timer);
01252     cancelAndDelete(timedoutMessages_timer);
01253     cancelAndDelete(timedoutNeighbors_timer);
01254     cancelAndDelete(sendKeyList_timer);
01255     cancelAndDelete(sendToken_timer);
01256     delete msgBookkeepingList;
01257 }
01258 
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3