Gia Class Reference

#include <Gia.h>

Inheritance diagram for Gia:

BaseOverlay BaseRpc TopologyVis RpcListener

List of all members.


Detailed Description

Gia overlay module.

Implementation of the Gia overlay as described in "Making Gnutella-like P2P Systems Scalable" by Y. Chawathe et al. published at SIGCOMM'03

Author:
Robert Palmer

Public Member Functions

void initializeOverlay (int stage)
 initializes base class-attributes
void finishOverlay ()
 Writes statistical data and removes node from bootstrap oracle.
virtual void changeState (int toStage)
 Set state to toStage.
void updateTooltip ()
 Marks nodes if they are ready.
 ~Gia ()
 Destructor.
void handleTimerEvent (cMessage *msg)
 Processes "timer" self-messages.
void handleUDPMessage (BaseOverlayMessage *msg)
 Processes messages from underlay.
virtual void route (const OverlayKey &key, CompType destComp, CompType srcComp, cMessage *msg, const TransportAddress &hint=TransportAddress::UNSPECIFIED_NODE)
 Sends a packet over UDP.
void handleAppMessage (cMessage *msg)
 Processes non-commonAPI messages.
void sendToken (const GiaNode &dst)

Protected Member Functions

void joinOverlay ()
 Join the overlay with a given nodeID in thisNode.key.
bool acceptNode (const GiaNode &newNode, unsigned int degree)
 Decides if Node newNode will be accepted as new neighor.
void addNeighbor (GiaNode &newNode, unsigned int degree)
 Adds newNode as new neighbor.
void removeNeighbor (const GiaNode &newNode)
 Removes newNode from our NeighborList.
double calculateLevelOfSatisfaction ()
 Calculates level of satisfaction.
void sendMessage_JOIN_REQ (const NodeHandle &dst)
 Sends JOIN_REQ_Message from node src to node dst.
void sendMessage_JOIN_RSP (const NodeHandle &dst)
 Sends JOIN_RSP_Message from node src to node dst.
void sendMessage_JOIN_ACK (const NodeHandle &dst)
 Sends JOIN_ACK_Message from node src to node dst.
void sendMessage_JOIN_DNY (const NodeHandle &dst)
 Sends JOIN_DNY_Message from node src to node dst.
void sendMessage_DISCONNECT (const NodeHandle &dst)
 Sends DISCONNECT_Message from node src to node dst.
void sendMessage_UPDATE (const NodeHandle &dst)
 Sends UPDATE_Message from node src to node dst.
void sendKeyListToNeighbor (const NodeHandle &dst)
 Sends KeyList to node dst.
void updateNeighborList (GiaMessage *msg)
 Updates neighborlist with new capacity and connectiondegree informations from received message msg.
void forwardSearchResponseMessage (SearchResponseMessage *msg)
 Forwards a search response message to the next node in reverse-path.
void forwardMessage (GiaIDMessage *msg, bool fromApplication)
 Forwards a message to the next random selected node, biased random walk.
void processSearchMessage (SearchMessage *msg, bool fromApplication)
 Processes search message msg.
void sendSearchResponseMessage (const GiaNode &srcNode, SearchMessage *msg)
 Sends a response message to a received search query.
void deliverSearchResult (SearchResponseMessage *msg)
 Delivers search result to application layer.

Protected Attributes

uint maxNeighbors
 maximum number of neighbors
uint minNeighbors
 minimum number of neighbors
uint maxTopAdaptionInterval
 maximum topology adaption interval
uint topAdaptionAggressiveness
 the topology adaption aggressiveness
double maxLevelOfSatisfaction
 maximum level of satisfaction
double updateDelay
 time between to update messages (in ms)
uint maxHopCount
 maximum time to live for sent messages
uint messageTimeout
 timeout for messages
uint neighborTimeout
 timeout for neighbors
uint sendTokenTimeout
 timeout for tokens
uint tokenWaitTime
 delay to send a new token
double keyListDelay
 delay to send the keylist to our neighbors
bool outputNodeDetails
 output of node details? (on std::cout)
bool optimizeReversePath
 use optimized reverse path?
double levelOfSatisfaction
 current level of statisfaction
unsigned int connectionDegree
unsigned int receivedTokens
unsigned int sentTokens
GiaNode thisGiaNode
 this node
NodeHandle bootstrapNode
 next possible neighbor candidate
GiaMessageBookkeepingmsgBookkeepingList
 pointer to a message bookkeeping list
uint stat_joinCount
 number of sent join messages
uint stat_joinBytesSent
 number of sent bytes of join messages
uint stat_joinREQ
 number of sent join request messages
uint stat_joinREQBytesSent
 number of sent bytes of join request messages
uint stat_joinRSP
 number of sent join response messages
uint stat_joinRSPBytesSent
 number of sent bytes of join response messages
uint stat_joinACK
 number of sent join acknowledge messages
uint stat_joinACKBytesSent
 number of sent bytes of join acknowledge messages
uint stat_joinDNY
 number of sent join deny messages
uint stat_joinDNYBytesSent
 number of sent bytes of join deny messages
uint stat_disconnectMessages
 number of sent disconnect messages
uint stat_disconnectMessagesBytesSent
 number of sent bytes of disconnect messages
uint stat_updateMessages
 number of sent update messages
uint stat_updateMessagesBytesSent
 number of sent bytes of update messages
uint stat_tokenMessages
 number of sent token messages
uint stat_tokenMessagesBytesSent
 number of sent bytes of token messages
uint stat_keyListMessages
 number of sent keylist messages
uint stat_keyListMessagesBytesSent
 number of sent bytes of keylist messages
uint stat_routeMessages
 number of sent route messages
uint stat_routeMessagesBytesSent
 number of sent bytes of route messages
uint stat_maxNeighbors
 maximum number of neighbors
uint stat_addedNeighbors
 number of added neighbors during life cycle of this node
uint stat_removedNeighbors
 number of removed neighbors during life cycle of this node
uint stat_numSatisfactionMessages
 number of satisfaction self-messages
double stat_sumLevelOfSatisfaction
 sum of level of satisfaction
double stat_maxLevelOfSatisfaction
 maximum level of satisfaction
cMessage * satisfaction_timer
 timer for satisfaction self-message
cMessage * update_timer
 timer for update self-message
cMessage * timedoutMessages_timer
 timer for message timeout
cMessage * timedoutNeighbors_timer
 timer for neighbors timeout
cMessage * sendKeyList_timer
 timer for send keylist
cMessage * sendToken_timer
 timer for send token
GiaKeyListModulekeyListModule
 pointer to KeyListModule
GiaNeighborsneighbors
 pointer to neighbor list
GiaTokenFactorytokenFactory
 pointer to TokenFactory
GiaNeighborCandidateList neighCand
 list of all neighbor candidates
GiaNeighborCandidateList knownNodes
 list of known nodes in the overlay
GiaKeyList keyList
 key list of this node

Constructor & Destructor Documentation

Gia::~Gia (  ) 

Destructor.

01244 {
01245     cancelAndDelete(satisfaction_timer);
01246     cancelAndDelete(update_timer);
01247     cancelAndDelete(timedoutMessages_timer);
01248     cancelAndDelete(timedoutNeighbors_timer);
01249     cancelAndDelete(sendKeyList_timer);
01250     cancelAndDelete(sendToken_timer);
01251     delete msgBookkeepingList;
01252 }


Member Function Documentation

void Gia::initializeOverlay ( int  stage  )  [virtual]

initializes base class-attributes

Parameters:
stage the init stage

Reimplemented from BaseOverlay.

00037 {
00038     // wait until IPAddressResolver initialized all interfaces and assigns addresses
00039     if(stage != MIN_STAGE_OVERLAY)
00040         return;
00041 
00042     // Get parameters from omnetpp.ini
00043     maxNeighbors = par("maxNeighbors");
00044     minNeighbors = par("minNeighbors");
00045     maxTopAdaptionInterval = par("maxTopAdaptionInterval");
00046     topAdaptionAggressiveness = par("topAdaptionAggressiveness");
00047     maxLevelOfSatisfaction = par("maxLevelOfSatisfaction");
00048     updateDelay = par("updateDelay");
00049     maxHopCount = par("maxHopCount"); //obsolete
00050     messageTimeout = par("messageTimeout");
00051     neighborTimeout = par("neighborTimeout");
00052     sendTokenTimeout = par("sendTokenTimeout");
00053     tokenWaitTime = par("tokenWaitTime");
00054     keyListDelay = par("keyListDelay");
00055     outputNodeDetails = par("outputNodeDetails");
00056     optimizeReversePath = par("optimizeReversePath");
00057 
00058     // get references on necessary modules
00059     keyListModule = check_and_cast<GiaKeyListModule*>
00060         (parentModule()->submodule("keyListModule"));
00061     neighbors = check_and_cast<GiaNeighbors*>
00062         (parentModule()->submodule("neighbors"));
00063     tokenFactory = check_and_cast<GiaTokenFactory*>
00064         (parentModule()->submodule("tokenFactory"));
00065 
00066     msgBookkeepingList = new GiaMessageBookkeeping(neighbors, messageTimeout);
00067 
00068     // clear neighbor candidate list
00069     neighCand.clear();
00070     knownNodes.clear();
00071 
00072     WATCH(thisGiaNode);
00073     WATCH(bootstrapNode);
00074     WATCH(levelOfSatisfaction);
00075 
00076     // self-messages
00077     satisfaction_timer = new cMessage("satisfaction_timer");
00078     update_timer = new cMessage("update_timer");
00079     timedoutMessages_timer = new cMessage("timedoutMessages_timer");
00080     timedoutNeighbors_timer = new cMessage("timedoutNeighbors_timer");
00081     sendKeyList_timer = new cMessage("sendKeyList_timer");
00082     sendToken_timer = new cMessage("sendToken_timer");
00083 
00084     // statistics
00085     stat_joinCount = 0;
00086     stat_joinBytesSent = 0;
00087     stat_joinREQ = 0;
00088     stat_joinREQBytesSent = 0;
00089     stat_joinRSP = 0;
00090     stat_joinRSPBytesSent = 0;
00091     stat_joinACK = 0;
00092     stat_joinACKBytesSent = 0;
00093     stat_joinDNY = 0;
00094     stat_joinDNYBytesSent = 0;
00095     stat_disconnectMessages = 0;
00096     stat_disconnectMessagesBytesSent = 0;
00097     stat_updateMessages = 0;
00098     stat_updateMessagesBytesSent = 0;
00099     stat_tokenMessages = 0;
00100     stat_tokenMessagesBytesSent = 0;
00101     stat_keyListMessages = 0;
00102     stat_keyListMessagesBytesSent = 0;
00103     stat_routeMessages = 0;
00104     stat_routeMessagesBytesSent = 0;
00105     stat_maxNeighbors = 0;
00106     stat_addedNeighbors = 0;
00107     stat_removedNeighbors = 0;
00108     stat_numSatisfactionMessages = 0;
00109     stat_sumLevelOfSatisfaction = 0.0;
00110     stat_maxLevelOfSatisfaction = 0.0;
00111 }

void Gia::finishOverlay (  )  [virtual]

Writes statistical data and removes node from bootstrap oracle.

Reimplemented from BaseOverlay.

01208 {
01209     // statistics
01210 
01211     globalStatistics->addStdDev("GIA: JOIN-Messages Count", stat_joinCount);
01212     globalStatistics->addStdDev("GIA: JOIN Bytes sent", stat_joinBytesSent);
01213     globalStatistics->addStdDev("GIA: JOIN::REQ Messages", stat_joinREQ);
01214     globalStatistics->addStdDev("GIA: JOIN::REQ Bytes sent", stat_joinREQBytesSent);
01215     globalStatistics->addStdDev("GIA: JOIN::RSP Messages", stat_joinRSP);
01216     globalStatistics->addStdDev("GIA: JOIN::RSP Bytes sent", stat_joinRSPBytesSent);
01217     globalStatistics->addStdDev("GIA: JOIN::ACK Messages", stat_joinACK);
01218     globalStatistics->addStdDev("GIA: JOIN::ACK Bytes sent", stat_joinACKBytesSent);
01219     globalStatistics->addStdDev("GIA: JOIN::DNY Messages", stat_joinDNY);
01220     globalStatistics->addStdDev("GIA: JOIN::DNY Bytes sent", stat_joinDNYBytesSent);
01221     globalStatistics->addStdDev("GIA: DISCONNECT:IND Messages", stat_disconnectMessages);
01222     globalStatistics->addStdDev("GIA: DISCONNECT:IND Bytes sent",
01223                                 stat_disconnectMessagesBytesSent);
01224     globalStatistics->addStdDev("GIA: UPDATE:IND Messages", stat_updateMessages);
01225     globalStatistics->addStdDev("GIA: UPDATE:IND Bytes sent", stat_updateMessagesBytesSent);
01226     globalStatistics->addStdDev("GIA: TOKEN:IND Messages", stat_tokenMessages);
01227     globalStatistics->addStdDev("GIA: TOKEN:IND Bytes sent", stat_tokenMessagesBytesSent);
01228     globalStatistics->addStdDev("GIA: KEYLIST:IND Messages", stat_keyListMessages);
01229     globalStatistics->addStdDev("GIA: KEYLIST:IND Bytes sent", stat_keyListMessagesBytesSent);
01230     globalStatistics->addStdDev("GIA: ROUTE:IND Messages", stat_routeMessages);
01231     globalStatistics->addStdDev("GIA: ROUTE:IND Bytes sent", stat_routeMessagesBytesSent);
01232     globalStatistics->addStdDev("GIA: Neighbors max", stat_maxNeighbors);
01233     globalStatistics->addStdDev("GIA: Neighbors added", stat_addedNeighbors);
01234     globalStatistics->addStdDev("GIA: Neighbors removed", stat_removedNeighbors);
01235     globalStatistics->addStdDev("GIA: Level of satisfaction messages ",
01236                                 stat_numSatisfactionMessages);
01237     globalStatistics->addStdDev("GIA: Level of satisfaction max ",stat_maxLevelOfSatisfaction);
01238     globalStatistics->addStdDev("GIA: Level of satisfaction avg ",
01239                                 stat_sumLevelOfSatisfaction / stat_numSatisfactionMessages);
01240     removeBootstrapNode(thisGiaNode);
01241 }

void Gia::changeState ( int  toStage  )  [virtual]

Set state to toStage.

Parameters:
toStage the stage to change to
00122 {
00123     switch (toState) {
00124     case INIT: {
00125         state = INIT;
00126 
00127         setOverlayReady(false);
00128         showOverlayNeighborArrow(thisGiaNode);
00129         
00130         // set up local nodehandle
00131         //thisGiaNode.setNodeHandle(thisNode);
00132         thisGiaNode = thisNode;
00133             
00134         callUpdate(thisNode, true);
00135 
00136         // get possible bandwidth from ppp-Module
00137         double capacity = 0;
00138 
00139         cModule* nodeModule = parentModule()->parentModule();
00140 
00141         int gateSize = nodeModule->gateSize("in");
00142 
00143         if(gateSize == 0)
00144             capacity += uniform(1,800000);
00145         else {
00146             // this relies on IPv4Underlay
00147             for (int i=0; i<gateSize; i++) {
00148                 int gateID = nodeModule->gate("in",0)->id()+i;
00149                 cGate* currentGate = nodeModule->gate(gateID);
00150                 if (currentGate->isConnected())
00151                     capacity += check_and_cast<cBasicChannel *>
00152                         (currentGate->fromGate()->channel())->datarate()
00153                         - uniform(0,800000);
00154             }
00155         }
00156 
00157         thisGiaNode.setCapacity(capacity);
00158         //thisGiaNode.setConnectionDegree(0);
00159         //thisGiaNode.setReceivedTokens(0);
00160         //thisGiaNode.setSentTokens(0);
00161 
00162         connectionDegree = 0;
00163         receivedTokens = 0;
00164         sentTokens = 0;
00165 
00166         if (outputNodeDetails)
00167             EV << "(Gia) Node details: " << thisGiaNode << endl;
00168 
00169         // get our entry point to GIA-Overlay 
00170         bootstrapNode = getBootstrapNode();
00171         if(!(bootstrapNode.isUnspecified()))
00172             knownNodes.add(bootstrapNode);
00173         //else {
00174         //assert(!(thisGiaNode.getNodeHandle().isUnspecified()));
00175         //bootstrapOracle->registerPeer(thisGiaNode.getNodeHandle());
00176         //}
00177 
00178         // register node at TokenFactory
00179         //tokenFactory->setNode(&thisGiaNode);
00180         tokenFactory->setNeighbors(neighbors);
00181         tokenFactory->setMaxHopCount(maxHopCount);
00182 
00183         if (debugOutput)
00184             EV << "(Gia) Node " << thisGiaNode.key
00185                << " (" << thisGiaNode.ip << ":"
00186                << thisGiaNode.port << ") with capacity: "
00187                << thisGiaNode.getCapacity()  << " entered INIT state." << endl;
00188 
00189         parentModule()->parentModule()->bubble("Enter INIT state.");
00190 
00191         // schedule satisfaction_timer
00192         cancelEvent(satisfaction_timer);
00193         scheduleAt(simulation.simTime(), satisfaction_timer);
00194 
00195         // schedule timedoutMessages_timer
00196         cancelEvent(timedoutMessages_timer);
00197         scheduleAt(simulation.simTime() + messageTimeout,
00198                    timedoutMessages_timer);
00199 
00200         cancelEvent(timedoutNeighbors_timer);
00201         scheduleAt(simulation.simTime() + neighborTimeout,
00202                    timedoutNeighbors_timer);
00203 
00204         cancelEvent(sendToken_timer);
00205         scheduleAt(simulation.simTime() + sendTokenTimeout,
00206                    sendToken_timer);
00207 
00208         break;
00209     }
00210     case READY:
00211         state = READY;
00212         setOverlayReady(true);
00213         break;
00214     }
00215     updateTooltip();
00216 }

void Gia::updateTooltip (  ) 

Marks nodes if they are ready.

00234 {
00235     if (ev.isGUI()) {
00236 //        if (state == READY) {
00237 //            parentModule()->parentModule()->displayString().
00238 //                setTagArg("i2", 1, "");
00239 //            displayString().setTagArg("i", 1, "");
00240 //        } else {
00241 //            parentModule()->parentModule()->displayString().
00242 //                setTagArg("i2", 1, "red");
00243 //            displayString().setTagArg("i", 1, "red");
00244 //        }
00245 
00246         std::stringstream ttString;
00247 
00248         // show our predecessor and successor in tooltip
00249         ttString << thisNode << "\n# Neighbors: " 
00250                  << neighbors->getSize();
00251 
00252         parentModule()->parentModule()->displayString().
00253             setTagArg("tt", 0, ttString.str().c_str());
00254         parentModule()->displayString().
00255             setTagArg("tt", 0, ttString.str().c_str());
00256         displayString().setTagArg("tt", 0, ttString.str().c_str());
00257     }
00258 }

void Gia::handleTimerEvent ( cMessage *  msg  )  [virtual]

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented from BaseOverlay.

00261 {
00262     if (msg == sendToken_timer) {
00263         tokenFactory->grantToken();
00264     } else if (msg->isName("satisfaction_timer")) {
00265         // calculate level of satisfaction and select new neighbor candidate
00266 
00267         levelOfSatisfaction = calculateLevelOfSatisfaction();
00268         stat_numSatisfactionMessages++;
00269         stat_sumLevelOfSatisfaction += levelOfSatisfaction;
00270         if (levelOfSatisfaction > stat_maxLevelOfSatisfaction)
00271             stat_maxLevelOfSatisfaction = levelOfSatisfaction;
00272 
00273         // start again satisfaction_timer
00274         scheduleAt(simulation.simTime() + (maxTopAdaptionInterval *
00275                                            pow(topAdaptionAggressiveness,
00276                                                -(1 - levelOfSatisfaction))),
00277                    satisfaction_timer);
00278 
00279         // Only search a new neighbor if level of satisfaction is
00280         // under level of maxLevelOfSatisfaction
00281         if(levelOfSatisfaction < maxLevelOfSatisfaction) {
00282             if(knownNodes.getSize() == 0)
00283                 if(neighbors->getSize() == 0 && neighCand.getSize() == 0)
00284                     knownNodes.add(getBootstrapNode());
00285                 else
00286                     return;
00287 
00288             NodeHandle possibleNeighbor = knownNodes.getRandomCandidate();
00289 
00290             if(!(possibleNeighbor.isUnspecified()) &&
00291                thisGiaNode != possibleNeighbor &&
00292                !neighbors->contains(possibleNeighbor) &&
00293                !neighCand.contains(possibleNeighbor)) {
00294                 // try to add new neighbor
00295                 neighCand.add(possibleNeighbor);
00296                 sendMessage_JOIN_REQ(possibleNeighbor);
00297             }
00298         }
00299     } else if (msg->isName("update_timer")) {
00300         // send current capacity and degree to all neighbors
00301         for (uint i=0; i<neighbors->getSize(); i++) {
00302             sendMessage_UPDATE(neighbors->get(i));
00303         }
00304     } else if (msg->isName("timedoutMessages_timer")) {
00305         // remove timedout messages
00306         msgBookkeepingList->removeTimedoutMessages();
00307         scheduleAt(simulation.simTime() + messageTimeout,
00308                    timedoutMessages_timer);
00309     } else if (msg->isName("timedoutNeighbors_timer")) {
00310         // remove timedout neighbors
00311         neighbors->removeTimedoutNodes();
00312         if (neighbors->getSize() == 0) {
00313             changeState(INIT);
00314         }
00315         cancelEvent(timedoutNeighbors_timer);
00316         scheduleAt(simulation.simTime() + neighborTimeout,
00317                    timedoutNeighbors_timer);
00318     } else if (msg->isName("sendKeyList_timer")) {
00319         if (keyList.getSize() > 0) {
00320             // send keyList to all of our neighbors
00321             for (uint i=0; i<neighbors->getSize(); i++)
00322                 sendKeyListToNeighbor(neighbors->get(i));
00323         }
00324     } else {
00325         // other self-messages are notoken-self-messages
00326         // with an encapsulated message
00327         const std::string id = msg->name();
00328         if (id.substr(0, 16) == std::string("wait-for-token: ")) {
00329             cMessage* decapsulatedMessage = msg->decapsulate();
00330             if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00331                 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00332                     (decapsulatedMessage);
00333                 forwardMessage(message, false);
00334             }
00335         } else if (id.substr(0, 24) == std::string("wait-for-token-fromapp: ")) {
00336             cMessage* decapsulatedMessage = msg->decapsulate();
00337             if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00338                 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00339                     (decapsulatedMessage);
00340                 forwardMessage(message, true);
00341             }
00342         }
00343         delete msg;
00344     }
00345 }

void Gia::handleUDPMessage ( BaseOverlayMessage *  msg  )  [virtual]

Processes messages from underlay.

Parameters:
msg Message from UDP

Reimplemented from BaseOverlay.

00348 {
00349     if(debugOutput)
00350         EV << "(Gia) " << thisGiaNode << " received udp message" << endl;
00351 
00352     cPolymorphic* ctrlInfo = msg->removeControlInfo();
00353     if(ctrlInfo != NULL)
00354         delete ctrlInfo;
00355 
00356     // Parse TokenMessages
00357     if (dynamic_cast<TokenMessage*>(msg) != NULL) {
00358         TokenMessage* giaMsg = check_and_cast<TokenMessage*>(msg);
00359 
00360         // Process TOKEN-Message
00361         if ((giaMsg->getCommand() == TOKEN)) {
00362             if(debugOutput)
00363                 EV << "(Gia) Received Tokenmessage from "
00364                            << giaMsg->getSrcNode() << endl;
00365 
00366             //neighbors->setReceivedTokens(giaMsg->getSrcNode(), giaMsg->getDstTokenNr());
00367             neighbors->increaseReceivedTokens(giaMsg->getSrcNode());
00368             updateNeighborList(giaMsg);
00369         }
00370         delete msg;
00371     }
00372 
00373     // Process Route messages
00374     else if (dynamic_cast<GiaRouteMessage*>(msg) != NULL) {
00375         GiaRouteMessage* giaMsg = check_and_cast<GiaRouteMessage*>(msg);
00376         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00377                              giaMsg->getSrcDegree());
00378 
00379         if((giaMsg->getCommand() == ROUTE)) {
00380             if(debugOutput)
00381                 EV << "(Gia) Received ROUTE::IND from " << oppositeNode << endl;
00382 
00383             if(state == READY) {
00384                 //neighbors->decreaseReceivedTokens(giaMsg->getSrcNode());
00385                 updateNeighborList(giaMsg);
00386                 forwardMessage(giaMsg, false);
00387             }
00388         }
00389     }
00390 
00391     // Process KeyList-Messages
00392     else if (dynamic_cast<KeyListMessage*>(msg) != NULL) {
00393         KeyListMessage* giaMsg = check_and_cast<KeyListMessage*>(msg);
00394         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00395                              giaMsg->getSrcDegree());
00396 
00397         if (giaMsg->getCommand() == KEYLIST) {
00398             if (debugOutput)
00399                 EV << "(Gia) " << thisGiaNode
00400                    << " received KEYLIST:IND message" << endl;
00401             // update KeyList in neighborList
00402             uint keyListSize = giaMsg->getKeysArraySize();
00403             GiaKeyList neighborKeyList;
00404             for (uint k = 0; k < keyListSize; k++)
00405                 neighborKeyList.addKeyItem(giaMsg->getKeys(k));
00406             neighbors->setNeighborKeyList(giaMsg->getSrcNode(), neighborKeyList);
00407         }
00408         delete giaMsg;
00409     }
00410 
00411     // Process Search-Messages
00412     else if (dynamic_cast<SearchMessage*>(msg) != NULL) {
00413         SearchMessage* giaMsg = check_and_cast<SearchMessage*>(msg);
00414         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00415                              giaMsg->getSrcDegree());
00416 
00417         //neighbors->decreaseSentTokens(giaMsg->getSrcNode());
00418         updateNeighborList(giaMsg);
00419         processSearchMessage(giaMsg, false);
00420         // } else {
00421         //             EV << "(Gia) Message " << msg << " dropped!" << endl;
00422         //             RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
00423         //             delete msg;
00424         //         }
00425     }
00426 
00427     // Process Search-Response-Messages
00428     else if (dynamic_cast<SearchResponseMessage*>(msg) != NULL) {
00429         SearchResponseMessage* responseMsg =
00430             check_and_cast<SearchResponseMessage*>(msg);
00431         forwardSearchResponseMessage(responseMsg);
00432     }
00433 
00434     // Process Gia messages
00435     else if (dynamic_cast<GiaMessage*>(msg) != NULL) {
00436         GiaMessage* giaMsg = check_and_cast<GiaMessage*>(msg);
00437 
00438         //assert(giaMsg->getSrcNode().moduleId != -1);
00439         GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00440                              giaMsg->getSrcDegree());
00441 
00442         if (debugOutput)
00443             EV << "(Gia) " << thisGiaNode << " received GIA- message from "
00444                << oppositeNode << endl;
00445         updateNeighborList(giaMsg);
00446 
00447         // Process JOIN:REQ messages
00448         if (giaMsg->getCommand() == JOIN_REQUEST) {
00449             if (debugOutput)
00450                 EV << "(Gia) " << thisGiaNode
00451                    << " received JOIN:REQ message" << endl;
00452             if (acceptNode(oppositeNode, giaMsg->getSrcDegree())) {
00453                 neighCand.add(oppositeNode);
00454                 sendMessage_JOIN_RSP(oppositeNode);
00455             } else {
00456                 if (debugOutput)
00457                     EV << "(Gia) " << thisGiaNode << " denies node "
00458                        << oppositeNode << endl;
00459                 sendMessage_JOIN_DNY(oppositeNode);
00460             }
00461         }
00462 
00463         // Process JOIN:RSP messages
00464         else if (giaMsg->getCommand() == JOIN_RESPONSE) {
00465             if(debugOutput)
00466                 EV << "(Gia) " << thisGiaNode << " received JOIN:RSP message"
00467                    << endl;
00468             if(neighCand.contains(oppositeNode)) {
00469                 neighCand.remove(oppositeNode);
00470                 if(acceptNode(oppositeNode, giaMsg->getSrcDegree())) {
00471                     addNeighbor(oppositeNode, giaMsg->getSrcDegree());
00472 
00473                     GiaNeighborMessage* msg =
00474                         check_and_cast<GiaNeighborMessage*>(giaMsg);
00475                     for(uint i = 0; i < msg->getNeighborsArraySize(); i++) {
00476                         GiaNode temp = msg->getNeighbors(i);
00477                         if(temp != thisGiaNode && temp != oppositeNode)
00478                             knownNodes.add(temp);
00479                     }
00480 
00481                     sendMessage_JOIN_ACK(oppositeNode);
00482                 } else {
00483                     if (debugOutput)
00484                         EV << "(Gia) " << thisGiaNode << " denies node "
00485                            << oppositeNode << endl;
00486                     sendMessage_JOIN_DNY(oppositeNode);
00487                 }
00488             }
00489         }
00490 
00491         // Process JOIN:ACK messages
00492         else if (giaMsg->getCommand() == JOIN_ACK) {
00493             if (debugOutput)
00494                 EV << "(Gia) " << thisGiaNode << " received JOIN:ACK message"
00495                    << endl;
00496             if (neighCand.contains(oppositeNode) &&
00497                 neighbors->getSize() < maxNeighbors) {
00498                 neighCand.remove(oppositeNode);
00499                 addNeighbor(oppositeNode, giaMsg->getSrcDegree());
00500 
00501                 GiaNeighborMessage* msg =
00502                     check_and_cast<GiaNeighborMessage*>(giaMsg);
00503 
00504                 for(uint i = 0; i < msg->getNeighborsArraySize(); i++) {
00505                     GiaNode temp = msg->getNeighbors(i);
00506                     if(temp != thisGiaNode && temp != oppositeNode)
00507                         knownNodes.add(msg->getNeighbors(i));
00508                 }
00509             } else {
00510                 sendMessage_DISCONNECT(oppositeNode);
00511             }
00512             
00513         }
00514 
00515         // Process JOIN:DNY messages
00516         else if (giaMsg->getCommand() == JOIN_DENY) {
00517             if (debugOutput)
00518                 EV << "(Gia) " << thisGiaNode << " received JOIN:DNY message"
00519                    << endl;
00520 
00521             if (neighCand.contains(oppositeNode))
00522                 neighCand.remove(oppositeNode);
00523             knownNodes.remove(oppositeNode);
00524 
00525         }
00526 
00527 
00528         // Process DISCONNECT-Message
00529         else if (giaMsg->getCommand() == DISCONNECT) {
00530             if (debugOutput)
00531                 EV << "(Gia) " << thisGiaNode << " received DISCONNECT:IND message" << endl;
00532             removeNeighbor(giaMsg->getSrcNode());
00533         }
00534 
00535         // Process UPDATE-Message
00536         else if (giaMsg->getCommand() == UPDATE) {
00537             if (debugOutput)
00538                 EV << "(Gia) " << thisGiaNode << " received UPDATE:IND message"
00539                    << endl;
00540 
00541             neighbors->setConnectionDegree(giaMsg->getSrcNode(),
00542                                            giaMsg->getSrcDegree());
00543             //neighbors->setCapacity(giaMsg->getSrcNode(),
00544             //giaMsg->getSrcCapacity());            
00545         } else {
00546             // Show unknown gia-messages
00547             if (debugOutput) {
00548                 EV << "(Gia) NODE: "<< thisGiaNode << endl
00549                    << "       Command: " << giaMsg->getCommand() << endl
00550                    << "       HopCount: " << giaMsg->getHopCount() << endl
00551                    << "       SrcKey: " << giaMsg->getSrcNode().key << endl
00552                    << "       SrcIP: " << giaMsg->getSrcNode().key << endl
00553                    << "       SrcPort: " << giaMsg->getSrcNode().port << endl
00554                    << "       SrcCapacity: " << giaMsg->getSrcCapacity() << endl
00555                    << "       SrcDegree: " << giaMsg->getSrcDegree() << endl;
00556 
00557                 RECORD_STATS(numDropped++;bytesDropped += giaMsg->byteLength());
00558             }
00559         }
00560         delete giaMsg;
00561     } else // PROCESS other messages than GiaMessages
00562         delete msg; // delete them all
00563 }

void Gia::route ( const OverlayKey key,
CompType  destComp,
CompType  srcComp,
cMessage *  msg,
const TransportAddress hint = TransportAddress::UNSPECIFIED_NODE 
) [virtual]

Sends a packet over UDP.

Prints a brief about packets having an attached UDPControlInfo (i.e. those which just arrived from UDP, or about to be send to UDP). Routes message through overlay.

The default implementation uses FindNode to determine next hops and a generic greedy routing algorithm provides with SendToKey.

Parameters:
key destination key
destComp the destination component
srcComp the source component
msg message to route
hint next hop (usually unused)

Reimplemented from BaseOverlay.

01005 {
01006     if ((destComp != TIER1_COMP) || (srcComp != TIER1_COMP)) {
01007         throw new cException("Gia::route(): Works currently "
01008                              "only with srcComp=destComp=TIER1_COMP!");
01009     }
01010     
01011     if (state == READY) {
01012         GiaRouteMessage* routeMsg = new GiaRouteMessage("ROUTE");
01013         routeMsg->setSignaling(false);
01014         routeMsg->setCommand(ROUTE);
01015         routeMsg->setHopCount(maxHopCount);
01016         routeMsg->setDestKey(key);
01017         routeMsg->setSrcNode(thisGiaNode);
01018         routeMsg->setSrcCapacity(thisGiaNode.getCapacity());
01019         routeMsg->setSrcDegree(connectionDegree);
01020         routeMsg->setOriginatorKey(thisGiaNode.key);
01021         routeMsg->setOriginatorIP(thisGiaNode.ip);
01022         routeMsg->setOriginatorPort(thisGiaNode.port);
01023         routeMsg->setID(OverlayKey::random());
01024         routeMsg->setLength(GIAROUTE_L(routeMsg));
01025         routeMsg->encapsulate(msg);
01026 
01027 
01028         forwardMessage(routeMsg, true);
01029     } else {
01030         RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
01031         delete msg;
01032     }
01033 }

void Gia::handleAppMessage ( cMessage *  msg  )  [virtual]

Processes non-commonAPI messages.

Parameters:
msg non-commonAPIMessage

Reimplemented from BaseOverlay.

01036 {
01037     // do we receive a keylist?
01038     if (dynamic_cast<GIAput*>(msg) != NULL) {
01039         GIAput* putMsg = check_and_cast<GIAput*>(msg);
01040         uint keyListSize = putMsg->getKeysArraySize();
01041         for (uint k=0; k<keyListSize; k++)
01042             keyList.addKeyItem(putMsg->getKeys(k));
01043 
01044         // actualize vector in KeyListModule
01045         keyListModule->setKeyListVector(keyList.getVector());
01046 
01047         scheduleAt(simulation.simTime() + keyListDelay, sendKeyList_timer);
01048 
01049         delete putMsg;
01050     } else if (dynamic_cast<GIAsearch*>(msg) != NULL) {
01051         if (state == READY) {
01052             GIAsearch* getMsg = check_and_cast<GIAsearch*>(msg);
01053             SearchMessage* searchMsg = new SearchMessage("SEARCH");
01054             searchMsg->setCommand(SEARCH);
01055             searchMsg->setSignaling(false);
01056             searchMsg->setHopCount(maxHopCount);
01057             searchMsg->setDestKey(getMsg->getSearchKey());
01058             searchMsg->setSrcNode(thisGiaNode);
01059             searchMsg->setSrcCapacity(thisGiaNode.getCapacity());
01060             searchMsg->setSrcDegree(connectionDegree);
01061             searchMsg->setSearchKey(getMsg->getSearchKey());
01062             searchMsg->setMaxResponses(getMsg->getMaxResponses());
01063             searchMsg->setReversePathArraySize(0);
01064             searchMsg->setID(OverlayKey::random());
01065             searchMsg->setLength(SEARCH_L(searchMsg));
01066 
01067             processSearchMessage(searchMsg, true);
01068 
01069             delete getMsg;
01070         } else
01071             delete msg;
01072     } else {
01073         delete msg;
01074         EV << "(Gia) unkown message from app deleted!" << endl;
01075     }
01076 }

void Gia::sendToken ( const GiaNode dst  ) 

00798 {
00799     TokenMessage* tokenMsg = new TokenMessage("TOKEN");
00800     tokenMsg->setCommand(TOKEN);
00801     tokenMsg->setHopCount(maxHopCount);
00802     tokenMsg->setSrcNode(thisGiaNode);
00803     tokenMsg->setSrcCapacity(thisGiaNode.getCapacity());
00804     tokenMsg->setSrcDegree(connectionDegree);
00805     tokenMsg->setSrcTokenNr(0/*dst.getReceivedTokens()*/);//???
00806     tokenMsg->setDstTokenNr(/*dst.getSentTokens()+*/1);
00807     tokenMsg->setLength(TOKEN_L(tokenMsg));
00808 
00809     stat_tokenMessagesBytesSent += tokenMsg->byteLength();
00810     stat_tokenMessages += 1;
00811 
00812     sendMessageToUDP(dst, tokenMsg);
00813 }

void Gia::joinOverlay (  )  [protected, virtual]

Join the overlay with a given nodeID in thisNode.key.

Join the overlay with a given nodeID in thisNode.key. This method may be called by an application to join the overlay with a specific nodeID. It is also called if the node's IP address changes.

Reimplemented from BaseOverlay.

00114 {
00115     changeState(INIT);
00116 
00117     if (bootstrapNode.isUnspecified())
00118         changeState(READY);
00119 }

bool Gia::acceptNode ( const GiaNode newNode,
unsigned int  degree 
) [protected]

Decides if Node newNode will be accepted as new neighor.

Parameters:
newNode Node to accept or deny
degree the node's connection degree
Returns:
boolean true or false
00566 {
00567     if (neighbors->contains(nNode))
00568         return false;
00569 
00570     if (neighbors->getSize() < maxNeighbors) {
00571         // we have room for new node: accept node
00572         return true;
00573     }
00574     // we need to drop a neighbor
00575     NodeHandle dropCandidate = neighbors->getDropCandidate(nNode.getCapacity(), degree);
00576     if(!dropCandidate.isUnspecified()) {
00577         if (debugOutput)
00578             EV << "(Gia) " << thisGiaNode << " drops "
00579                << dropCandidate <<  endl;
00580         neighbors->remove(dropCandidate);
00581         sendMessage_DISCONNECT(dropCandidate);
00582         return true;
00583     }       
00584     return false;
00585 }

void Gia::addNeighbor ( GiaNode newNode,
unsigned int  degree 
) [protected]

Adds newNode as new neighbor.

Parameters:
newNode the node to add as a neighbor
degree the node's connection degree
00589 {
00590     assert(neighbors->getSize() < maxNeighbors);
00591 
00592     stat_addedNeighbors++;
00593     EV << "(Gia) " << thisGiaNode << " accepted new neighbor " << node << endl;
00594     parentModule()->parentModule()->bubble("New neighbor");
00595     connectionDegree = neighbors->getSize();
00596     changeState(READY);
00597     if (stat_maxNeighbors < neighbors->getSize()) {
00598         stat_maxNeighbors = neighbors->getSize();
00599     }
00600 
00601     cancelEvent(update_timer);
00602     scheduleAt(simulation.simTime() + updateDelay, update_timer);
00603 
00604     //node.setSentTokens(5);
00605     //node.setReceivedTokens(5);
00606 
00607     // send keyList to new Neighbor
00608     if (keyList.getSize() > 0)
00609         sendKeyListToNeighbor(node);
00610     neighbors->add(node, degree);
00611 
00612     showOverlayNeighborArrow(node, false,
00613                              "m=m,50,0,50,0;o=red,1");
00614     updateTooltip();
00615 }

void Gia::removeNeighbor ( const GiaNode newNode  )  [protected]

Removes newNode from our NeighborList.

Parameters:
newNode NodeHandle of the node to remove from neighbors
00618 {
00619     stat_removedNeighbors++;
00620 
00621     if (debugOutput)
00622         EV << "(Gia) " << thisGiaNode << " removes " << node
00623            << " from neighborlist." << endl;
00624     neighbors->remove(node);
00625 
00626     connectionDegree = neighbors->getSize();
00627 
00628     if (neighbors->getSize() == 0) {
00629         changeState(INIT);
00630     }
00631 
00632     deleteOverlayNeighborArrow(node);
00633     updateTooltip();
00634 
00635     cancelEvent(update_timer);
00636     scheduleAt(simulation.simTime() + updateDelay, update_timer);
00637 }

double Gia::calculateLevelOfSatisfaction (  )  [protected]

Calculates level of satisfaction.

Returns:
levelOfSatisfaction value
00640 {
00641     uint neighborsCount = neighbors->getSize();
00642     if(neighborsCount < minNeighbors)
00643         return 0.0;
00644 
00645     double total = 0.0;
00646     double levelOfSatisfaction = 0.0;
00647 
00648     for (uint i=0; i < neighborsCount; i++)
00649         total += neighbors->get(i).getCapacity() / neighborsCount;
00650 
00651     assert(thisGiaNode.getCapacity() != 0);
00652     levelOfSatisfaction = total / thisGiaNode.getCapacity();
00653 
00654     if ((levelOfSatisfaction > 1.0) || (neighborsCount >= maxNeighbors))
00655         return 1.0;
00656     return levelOfSatisfaction;
00657 }

void Gia::sendMessage_JOIN_REQ ( const NodeHandle dst  )  [protected]

Sends JOIN_REQ_Message from node src to node dst.

Parameters:
dst,: Destination
00661 {
00662     // send JOIN:REQ message
00663     GiaMessage* msg = new GiaMessage("JOIN_REQ");
00664     msg->setCommand(JOIN_REQUEST);
00665     msg->setSrcNode(thisGiaNode);
00666     msg->setSrcCapacity(thisGiaNode.getCapacity());
00667     msg->setSrcDegree(connectionDegree);
00668     msg->setLength(GIA_L(msg));
00669 
00670     stat_joinCount += 1;
00671     stat_joinBytesSent += msg->byteLength();
00672     stat_joinREQ += 1;
00673     stat_joinREQBytesSent += msg->byteLength();
00674 
00675     sendMessageToUDP(dst, msg);
00676 }

void Gia::sendMessage_JOIN_RSP ( const NodeHandle dst  )  [protected]

Sends JOIN_RSP_Message from node src to node dst.

Parameters:
dst,: Destination
00679 {
00680     // send JOIN:RSP message
00681     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_RSP");
00682     msg->setCommand(JOIN_RESPONSE);
00683     msg->setSrcNode(thisGiaNode);
00684     msg->setSrcCapacity(thisGiaNode.getCapacity());
00685     msg->setSrcDegree(connectionDegree);
00686 
00687     msg->setNeighborsArraySize(neighbors->getSize());
00688     //TODO: add parameter maxSendNeighbors
00689     for(uint i = 0; i < neighbors->getSize(); i++)
00690         msg->setNeighbors(i, neighbors->get(i));
00691 
00692     msg->setLength(GIANEIGHBOR_L(msg));
00693 
00694     stat_joinCount += 1;
00695     stat_joinBytesSent += msg->byteLength();
00696     stat_joinRSP += 1;
00697     stat_joinRSPBytesSent += msg->byteLength();
00698 
00699     sendMessageToUDP(dst, msg);
00700 }

void Gia::sendMessage_JOIN_ACK ( const NodeHandle dst  )  [protected]

Sends JOIN_ACK_Message from node src to node dst.

Parameters:
dst,: Destination
00703 {
00704     // send JOIN:ACK message
00705     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_ACK");
00706     msg->setCommand(JOIN_ACK);
00707     msg->setSrcNode(thisGiaNode);
00708     msg->setSrcCapacity(thisGiaNode.getCapacity());
00709     msg->setSrcDegree(connectionDegree);
00710 
00711     msg->setNeighborsArraySize(neighbors->getSize());
00712     //TODO: add parameter maxSendNeighbors
00713     for(uint i = 0; i < neighbors->getSize(); i++)
00714         msg->setNeighbors(i, neighbors->get(i));
00715 
00716     msg->setLength(GIANEIGHBOR_L(msg));
00717 
00718     stat_joinCount += 1;
00719     stat_joinBytesSent += msg->byteLength();
00720     stat_joinACK += 1;
00721     stat_joinACKBytesSent += msg->byteLength();
00722 
00723     sendMessageToUDP(dst, msg);
00724 }

void Gia::sendMessage_JOIN_DNY ( const NodeHandle dst  )  [protected]

Sends JOIN_DNY_Message from node src to node dst.

Parameters:
dst,: Destination
00727 {
00728     // send JOIN:DNY message
00729     GiaMessage* msg = new GiaMessage("JOIN_DENY");
00730     msg->setCommand(JOIN_DENY);
00731     msg->setSrcNode(thisGiaNode);
00732     msg->setSrcCapacity(thisGiaNode.getCapacity());
00733     msg->setSrcDegree(connectionDegree);
00734     msg->setLength(GIA_L(msg));
00735 
00736     stat_joinCount += 1;
00737     stat_joinBytesSent += msg->byteLength();
00738     stat_joinDNY += 1;
00739     stat_joinDNYBytesSent += msg->byteLength();
00740 
00741     sendMessageToUDP(dst, msg);
00742 }

void Gia::sendMessage_DISCONNECT ( const NodeHandle dst  )  [protected]

Sends DISCONNECT_Message from node src to node dst.

Parameters:
dst,: Destination
00745 {
00746     // send DISCONNECT:IND message
00747     GiaMessage* msg = new GiaMessage("DISCONNECT");
00748     msg->setCommand(DISCONNECT);
00749     msg->setSrcNode(thisGiaNode);
00750     msg->setSrcCapacity(thisGiaNode.getCapacity());
00751     msg->setSrcDegree(connectionDegree);
00752     msg->setLength(GIA_L(msg));
00753 
00754     stat_disconnectMessagesBytesSent += msg->byteLength();
00755     stat_disconnectMessages += 1;
00756 
00757     sendMessageToUDP(dst, msg);
00758 }

void Gia::sendMessage_UPDATE ( const NodeHandle dst  )  [protected]

Sends UPDATE_Message from node src to node dst.

Parameters:
dst,: Destination
00761 {
00762     // send UPDATE:IND message
00763     GiaMessage* msg = new GiaMessage("UPDATE");
00764     msg->setCommand(UPDATE);
00765     msg->setSrcNode(thisGiaNode);
00766     msg->setSrcCapacity(thisGiaNode.getCapacity());
00767     msg->setSrcDegree(connectionDegree);
00768     msg->setLength(GIA_L(msg));
00769 
00770     stat_updateMessagesBytesSent += msg->byteLength();
00771     stat_updateMessages += 1;
00772 
00773     sendMessageToUDP(dst, msg);
00774 }

void Gia::sendKeyListToNeighbor ( const NodeHandle dst  )  [protected]

Sends KeyList to node dst.

Parameters:
dst,: Destination
00777 {
00778     // send KEYLIST:IND message
00779     KeyListMessage* msg = new KeyListMessage("KEYLIST");
00780     msg->setCommand(KEYLIST);
00781     msg->setSrcNode(thisGiaNode);
00782     msg->setSrcCapacity(thisGiaNode.getCapacity());
00783     msg->setSrcDegree(connectionDegree);
00784 
00785     msg->setKeysArraySize(keyList.getSize());
00786     for (uint i=0; i<keyList.getSize(); i++)
00787         msg->setKeys(i, keyList.get(i));
00788 
00789     msg->setLength(KEYLIST_L(msg));
00790 
00791     stat_keyListMessagesBytesSent += msg->byteLength();
00792     stat_keyListMessages += 1;
00793 
00794     sendMessageToUDP(dst, msg);
00795 }

void Gia::updateNeighborList ( GiaMessage *  msg  )  [protected]

Updates neighborlist with new capacity and connectiondegree informations from received message msg.

Parameters:
msg Received message
00816 {
00817     if(neighbors->contains(msg->getSrcNode().key)) {
00818         neighbors->setConnectionDegree(msg->getSrcNode(),msg->getSrcDegree());
00819         //neighbors->setCapacity(msg->getSrcNode(), msg->getSrcCapacity());
00820         neighbors->updateTimestamp(msg->getSrcNode());
00821     }
00822 }

void Gia::forwardSearchResponseMessage ( SearchResponseMessage *  msg  )  [protected]

Forwards a search response message to the next node in reverse-path.

Parameters:
msg Message to forward to next node
00825 {
00826     if (responseMsg->getHopCount() != 0) {
00827         uint reversePathArraySize = responseMsg->getReversePathArraySize();
00828 
00829         // reached node which started search?
00830         if (reversePathArraySize == 0) {
00831             deliverSearchResult(responseMsg);
00832         }
00833         // forward message to next node in reverse path list
00834         else {
00835             NodeHandle targetNode = neighbors->get
00836                 (responseMsg->getReversePath(
00837                                              reversePathArraySize-1));
00838 
00839             if(!(targetNode.isUnspecified())) {
00840                 responseMsg->setDestKey(targetNode.key);
00841                 responseMsg->setReversePathArraySize(reversePathArraySize-1);
00842                 for (uint i=0; i<reversePathArraySize-1; i++)
00843                     responseMsg->setReversePath(i, responseMsg->getReversePath(i));
00844                 responseMsg->setLength(responseMsg->length() - KEY_L);
00845 
00846                 stat_routeMessagesBytesSent += responseMsg->byteLength();
00847                 stat_routeMessages += 1;
00848 
00849                 if(responseMsg->getHopCount() > 0)
00850                     RECORD_STATS(numForwarded++; bytesForwarded +=
00851                                  responseMsg->byteLength());
00852 
00853                 sendMessageToUDP(targetNode, responseMsg);
00854             } else {
00855                 EV << "(Gia) wrong reverse path in " << *responseMsg
00856                    << " ... deleted!" << endl;
00857                 RECORD_STATS(numDropped++;
00858                              bytesDropped += responseMsg->byteLength());
00859                 delete responseMsg;
00860             }
00861         }
00862     }
00863     // max hopcount reached. delete message
00864     else
00865         delete responseMsg;
00866 }

void Gia::forwardMessage ( GiaIDMessage *  msg,
bool  fromApplication 
) [protected]

Forwards a message to the next random selected node, biased random walk.

Parameters:
msg Message to forward to next node
fromApplication Marks if message is from application layer
00869 {
00870     if (msg->getHopCount() == 0) {
00871         // Max-Hopcount reached. Discard message
00872         if (!fromApplication)
00873             tokenFactory->grantToken();
00874         RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
00875         delete msg;
00876     } else {
00877         // local delivery?
00878         if (msg->getDestKey() == thisGiaNode.key) {
00879             if(!fromApplication)
00880                 tokenFactory->grantToken();
00881 
00882             if(debugOutput)
00883                 EV << "(Gia) Deliver messsage " << msg
00884                    << " to application at " << thisGiaNode << endl;
00885 
00886             OverlayCtrlInfo* overlayCtrlInfo =
00887                 new OverlayCtrlInfo();
00888 
00889             overlayCtrlInfo->setHopCount(msg->getHopCount());
00890             overlayCtrlInfo->setSrcNode(msg->getSrcNode());
00891             overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00892             overlayCtrlInfo->setDestComp(TIER1_COMP); // workaround
00893             overlayCtrlInfo->setSrcComp(TIER1_COMP);
00894             
00895             msg->setControlInfo(overlayCtrlInfo);
00896             callDeliver(msg, msg->getDestKey());
00897         } else {
00898             // forward message to next hop
00899 
00900             // do we know the destination-node?
00901             if (neighbors->contains(msg->getDestKey())) {
00902                 // yes, destination-Node is our neighbor
00903                 NodeHandle targetNode = neighbors->get(msg->getDestKey());
00904                 GiaNeighborInfo* targetInfo= neighbors->get(targetNode);
00905 
00906                 if (targetInfo->receivedTokens == 0) {
00907                     // wait for free token
00908                     if (debugOutput)
00909                         EV << "(Gia) No free Node, wait for free token" << endl;
00910 
00911                     //bad code
00912                     std::string id;
00913                     if (!fromApplication)
00914                         id = "wait-for-token: " + msg->getID().toString();
00915                     else
00916                         id = "wait-for-token-fromapp: " +
00917                             msg->getID().toString();
00918                     cMessage* wait_timer = new cMessage(id.c_str());
00919                     wait_timer->encapsulate(msg);
00920                     scheduleAt(simulation.simTime() + tokenWaitTime,wait_timer);
00921                     return;
00922                 } else {
00923                     // decrease nextHop-tokencount
00924                     neighbors->decreaseReceivedTokens(targetNode);
00925                     //targetInfo->receivedTokens = targetInfo->receivedTokens - 1;
00926 
00927                     // forward msg to nextHop
00928                     msg->setHopCount(msg->getHopCount()-1);
00929                     msg->setSrcNode(thisGiaNode);
00930                     msg->setSrcCapacity(thisGiaNode.getCapacity());
00931                     msg->setSrcDegree(connectionDegree);
00932                     if (debugOutput)
00933                         EV << "(Gia) Forwarding message " << msg
00934                            << " to neighbor " << targetNode << endl;
00935                     if (!fromApplication)
00936                         tokenFactory->grantToken();
00937 
00938                     stat_routeMessagesBytesSent += msg->byteLength();
00939                     stat_routeMessages += 1;
00940 
00941                     if(msg->getHopCount() > 0)
00942                         RECORD_STATS(numForwarded++; bytesForwarded +=
00943                                      msg->byteLength());
00944 
00945                     sendMessageToUDP(targetNode, msg);
00946                 }
00947             } else {
00948                 // no => pick node with at least one token and highest capacity
00949                 if (!msgBookkeepingList->contains(msg))
00950                     msgBookkeepingList->addMessage(msg);
00951                 NodeHandle nextHop = msgBookkeepingList->getNextHop(msg);
00952                 // do we have a neighbor who send us a token?
00953                 if(nextHop.isUnspecified()) {
00954                     // wait for free token
00955                     if (debugOutput)
00956                         EV << "(Gia) No free Node, wait for free token" << endl;
00957                     std::string id;
00958                     if (!fromApplication)
00959                         id = "wait-for-token: " + msg->getID().toString();
00960                     else
00961                         id = "wait-for-token-fromapp: " +
00962                             msg->getID().toString();
00963                     cMessage* wait_timer = new cMessage(id.c_str());
00964                     wait_timer->encapsulate(msg);
00965                     scheduleAt(simulation.simTime() + tokenWaitTime,wait_timer);
00966                     return;
00967                 } else {
00968                     GiaNeighborInfo* nextHopInfo = neighbors->get(nextHop);
00969                     if(nextHopInfo == NULL) {
00970                         delete msg;
00971                         return; //???
00972                     }
00973                     // decrease nextHop-tokencount
00974                     neighbors->decreaseReceivedTokens(nextHop);
00975                     //nextHopInfo->receivedTokens--;
00976 
00977                     // forward msg to nextHop
00978                     msg->setHopCount(msg->getHopCount()-1);
00979                     msg->setSrcNode(thisGiaNode);
00980                     msg->setSrcCapacity(thisGiaNode.getCapacity());
00981                     msg->setSrcDegree(connectionDegree);
00982                     if (debugOutput)
00983                         EV << "(Gia) Forwarding message " << msg
00984                            << " to " << nextHop << endl;
00985                     if (!fromApplication)
00986                         tokenFactory->grantToken();
00987 
00988                     stat_routeMessagesBytesSent += msg->byteLength();
00989                     stat_routeMessages += 1;
00990 
00991                     if(msg->getHopCount() > 0)
00992                         RECORD_STATS(numForwarded++; bytesForwarded +=
00993                                      msg->byteLength());
00994 
00995                     sendMessageToUDP(nextHop, msg);
00996                 }
00997             }
00998         }
00999     }
01000 }

void Gia::processSearchMessage ( SearchMessage *  msg,
bool  fromApplication 
) [protected]

Processes search message msg.

Generates Search_Response_Messages

Parameters:
msg Search message
fromApplication Marks if message is from application layer
01143 {
01144     OverlayKey searchKey = msg->getSearchKey();
01145 
01146     if (keyList.contains(searchKey)) {
01147         // this node contains search key
01148         sendSearchResponseMessage(thisGiaNode, msg);
01149     }
01150 
01151     // check if neighbors contain search key
01152     for (uint i = 0; i < neighbors->getSize(); i++) {
01153         GiaKeyList* keyList = neighbors->getNeighborKeyList(neighbors->get(i));
01154         if (keyList->contains(searchKey))
01155             sendSearchResponseMessage(neighbors->get(i), msg);
01156     }
01157 
01158     // forward search-message to next hop
01159     if (msg->getMaxResponses() > 0) {
01160         // actualize reverse path
01161         uint reversePathSize = msg->getReversePathArraySize();
01162 
01163         if (optimizeReversePath)
01164             for (uint i=0; i<reversePathSize; i++) {
01165                 if (msg->getReversePath(i) == thisGiaNode.key) {
01166                     // Our node already in ReversePath.
01167                     // Delete successor nodes from ReversePath
01168                     msg->setLength(msg->length() - (reversePathSize - i)*KEY_L);
01169                     reversePathSize = i; // set new array size
01170                     break;
01171                 }
01172             }
01173 
01174         msg->setReversePathArraySize(reversePathSize+1);
01175         msg->setReversePath(reversePathSize, thisGiaNode.key);
01176         msg->setLength(msg->length() + KEY_L);
01177 
01178         forwardMessage(msg, fromApplication);
01179     } else {
01180         tokenFactory->grantToken();
01181         delete msg;
01182     }
01183 }

void Gia::sendSearchResponseMessage ( const GiaNode srcNode,
SearchMessage *  msg 
) [protected]

Sends a response message to a received search query.

Parameters:
srcNode Node which contains the searched key
msg SearchMessage
01080 {
01081     // does SearchMessage->foundNode[] already contain this node
01082     uint foundNodeArraySize = msg->getFoundNodeArraySize();
01083     bool containsNode = false;
01084     for (uint i=0; i<foundNodeArraySize; i++)
01085         if (srcNode.key == msg->getFoundNode(i))
01086             containsNode = true;
01087 
01088     if (!containsNode && msg->getMaxResponses() > 0) {
01089         // add this node to SearchMessage->foundNode[]
01090         msg->setFoundNodeArraySize(foundNodeArraySize+1);
01091         msg->setFoundNode(foundNodeArraySize, srcNode.key);
01092 
01093         // decrease SearchMessage->maxResponses
01094         msg->setMaxResponses(msg->getMaxResponses()-1);
01095 
01096         // get first node in reverse-path
01097         uint reversePathArraySize = msg->getReversePathArraySize();
01098 
01099         if (reversePathArraySize == 0) {
01100             // we have the key
01101             // deliver response to application
01102             SearchResponseMessage* responseMsg =
01103                 new SearchResponseMessage("ANSWER");
01104             responseMsg->setCommand(ANSWER);
01105             responseMsg->setSignaling(false);
01106             responseMsg->setHopCount(maxHopCount);
01107             responseMsg->setSrcNode(thisGiaNode);
01108             responseMsg->setSrcCapacity(thisGiaNode.getCapacity());
01109             responseMsg->setSrcDegree(connectionDegree);
01110             responseMsg->setSearchKey(msg->getSearchKey());
01111             responseMsg->setFoundNode(srcNode);
01112             responseMsg->setID(OverlayKey::random());
01113             responseMsg->setSearchHopCount(0);
01114 
01115             responseMsg->setLength(SEARCHRESPONSE_L(responseMsg));
01116 
01117             deliverSearchResult(responseMsg);
01118         } else {
01119             uint reversePathArraySize(msg->getReversePathArraySize());
01120             SearchResponseMessage* responseMsg =
01121                 new SearchResponseMessage("ANSWER");
01122             responseMsg->setCommand(ANSWER);
01123             responseMsg->setHopCount(maxHopCount);
01124             responseMsg->setSrcNode(srcNode);
01125             responseMsg->setSrcCapacity(srcNode.getCapacity());
01126             responseMsg->setSrcDegree(connectionDegree);
01127             responseMsg->setSearchKey(msg->getSearchKey());
01128             responseMsg->setFoundNode(srcNode);
01129             responseMsg->setReversePathArraySize(reversePathArraySize);
01130             for (uint i=0; i<reversePathArraySize; i++)
01131                 responseMsg->setReversePath(i, msg->getReversePath(i));
01132             responseMsg->setID(OverlayKey::random());
01133             responseMsg->setSearchHopCount(reversePathArraySize);
01134             responseMsg->setLength(SEARCHRESPONSE_L(responseMsg));
01135 
01136             forwardSearchResponseMessage(responseMsg);
01137         }
01138     }
01139 }

void Gia::deliverSearchResult ( SearchResponseMessage *  msg  )  [protected]

Delivers search result to application layer.

Parameters:
msg Search response message
01186 {
01187     OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo();
01188     overlayCtrlInfo->setHopCount(msg->getSearchHopCount());
01189     overlayCtrlInfo->setSrcNode(msg->getSrcNode());
01190     overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
01191 
01192     GIAanswer* deliverMsg = new GIAanswer("GIA-Answer");
01193     deliverMsg->setCommand(GIA_ANSWER);
01194     deliverMsg->setControlInfo(overlayCtrlInfo);
01195     deliverMsg->setSearchKey(msg->getSearchKey());
01196     deliverMsg->setNode(msg->getFoundNode());
01197     deliverMsg->setLength(GIAGETRSP_L(msg));
01198 
01199     send(deliverMsg, "to_app");
01200     if (debugOutput)
01201         EV << "(Gia) Deliver search response " << msg
01202            << " to application at " << thisGiaNode << endl;
01203 
01204     delete msg;
01205 }


Member Data Documentation

uint Gia::maxNeighbors [protected]

maximum number of neighbors

uint Gia::minNeighbors [protected]

minimum number of neighbors

uint Gia::maxTopAdaptionInterval [protected]

maximum topology adaption interval

uint Gia::topAdaptionAggressiveness [protected]

the topology adaption aggressiveness

double Gia::maxLevelOfSatisfaction [protected]

maximum level of satisfaction

double Gia::updateDelay [protected]

time between to update messages (in ms)

uint Gia::maxHopCount [protected]

maximum time to live for sent messages

uint Gia::messageTimeout [protected]

timeout for messages

uint Gia::neighborTimeout [protected]

timeout for neighbors

uint Gia::sendTokenTimeout [protected]

timeout for tokens

uint Gia::tokenWaitTime [protected]

delay to send a new token

double Gia::keyListDelay [protected]

delay to send the keylist to our neighbors

bool Gia::outputNodeDetails [protected]

output of node details? (on std::cout)

bool Gia::optimizeReversePath [protected]

use optimized reverse path?

double Gia::levelOfSatisfaction [protected]

current level of statisfaction

unsigned int Gia::connectionDegree [protected]

unsigned int Gia::receivedTokens [protected]

unsigned int Gia::sentTokens [protected]

GiaNode Gia::thisGiaNode [protected]

this node

NodeHandle Gia::bootstrapNode [protected]

next possible neighbor candidate

GiaMessageBookkeeping* Gia::msgBookkeepingList [protected]

pointer to a message bookkeeping list

uint Gia::stat_joinCount [protected]

number of sent join messages

uint Gia::stat_joinBytesSent [protected]

number of sent bytes of join messages

uint Gia::stat_joinREQ [protected]

number of sent join request messages

uint Gia::stat_joinREQBytesSent [protected]

number of sent bytes of join request messages

uint Gia::stat_joinRSP [protected]

number of sent join response messages

uint Gia::stat_joinRSPBytesSent [protected]

number of sent bytes of join response messages

uint Gia::stat_joinACK [protected]

number of sent join acknowledge messages

uint Gia::stat_joinACKBytesSent [protected]

number of sent bytes of join acknowledge messages

uint Gia::stat_joinDNY [protected]

number of sent join deny messages

uint Gia::stat_joinDNYBytesSent [protected]

number of sent bytes of join deny messages

uint Gia::stat_disconnectMessages [protected]

number of sent disconnect messages

uint Gia::stat_disconnectMessagesBytesSent [protected]

number of sent bytes of disconnect messages

uint Gia::stat_updateMessages [protected]

number of sent update messages

uint Gia::stat_updateMessagesBytesSent [protected]

number of sent bytes of update messages

uint Gia::stat_tokenMessages [protected]

number of sent token messages

uint Gia::stat_tokenMessagesBytesSent [protected]

number of sent bytes of token messages

uint Gia::stat_keyListMessages [protected]

number of sent keylist messages

uint Gia::stat_keyListMessagesBytesSent [protected]

number of sent bytes of keylist messages

uint Gia::stat_routeMessages [protected]

number of sent route messages

uint Gia::stat_routeMessagesBytesSent [protected]

number of sent bytes of route messages

uint Gia::stat_maxNeighbors [protected]

maximum number of neighbors

uint Gia::stat_addedNeighbors [protected]

number of added neighbors during life cycle of this node

uint Gia::stat_removedNeighbors [protected]

number of removed neighbors during life cycle of this node

uint Gia::stat_numSatisfactionMessages [protected]

number of satisfaction self-messages

double Gia::stat_sumLevelOfSatisfaction [protected]

sum of level of satisfaction

double Gia::stat_maxLevelOfSatisfaction [protected]

maximum level of satisfaction

cMessage* Gia::satisfaction_timer [protected]

timer for satisfaction self-message

cMessage* Gia::update_timer [protected]

timer for update self-message

cMessage* Gia::timedoutMessages_timer [protected]

timer for message timeout

cMessage* Gia::timedoutNeighbors_timer [protected]

timer for neighbors timeout

cMessage* Gia::sendKeyList_timer [protected]

timer for send keylist

cMessage* Gia::sendToken_timer [protected]

timer for send token

GiaKeyListModule* Gia::keyListModule [protected]

pointer to KeyListModule

GiaNeighbors* Gia::neighbors [protected]

pointer to neighbor list

GiaTokenFactory* Gia::tokenFactory [protected]

pointer to TokenFactory

GiaNeighborCandidateList Gia::neighCand [protected]

list of all neighbor candidates

GiaNeighborCandidateList Gia::knownNodes [protected]

list of known nodes in the overlay

GiaKeyList Gia::keyList [protected]

key list of this node


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:29 2008 for ITM OverSim by  doxygen 1.5.3