Gia Class Reference

#include <Gia.h>

Inheritance diagram for Gia:

BaseOverlay BaseRpc 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 receiveChangeNotification (int i, cPolymorphic *p)
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.
virtual void setBootstrapedIcon ()
 Marks nodes if they are ready.
 ~Gia ()
 Destructor.
void handleTimerEvent (cMessage *msg)
 Processes "timer" self-messages.
void handleUDPMessage (BaseOverlayMessage *msg)
 Processes messages from underlay.
void route (const OverlayKey &key, cMessage *msg, const NodeHandle &hint=NodeHandle::UNSPECIFIED_NODE)
 Route msg received from application layer to node with ID key.
void handleAppMessage (cMessage *msg)
 Processes non-commonAPI messages.
void sendToken (const GiaNode &dst)

Protected Member Functions

bool acceptNode (const GiaNode &newNode)
 Decides if Node newNode will be accepted as new neighor.
void addNeighbor (GiaNode &newNode)
 Adds newNode as new neighbor.
void removeNeighbor (const NodeHandle &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 GiaNode &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 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?
int state
 current state of this node (initialization, overlay (not) ready)
double levelOfSatisfaction
 current level of statisfaction
GiaNode thisNode
 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
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.

01195 {
01196     cancelAndDelete(satisfaction_timer);
01197     cancelAndDelete(update_timer);
01198     cancelAndDelete(timedoutMessages_timer);
01199     cancelAndDelete(timedoutNeighbors_timer);
01200     cancelAndDelete(sendKeyList_timer);
01201     delete msgBookkeepingList;
01202 }


Member Function Documentation

void Gia::receiveChangeNotification ( int  i,
cPolymorphic *  p 
) [inline]

00072     {}

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     tokenWaitTime = par("tokenWaitTime");
00053     keyListDelay = par("keyListDelay");
00054     outputNodeDetails = par("outputNodeDetails");
00055     optimizeReversePath = par("optimizeReversePath");
00056 
00057     onlyCommonAPIMessages = false;
00058 
00059     // get references on necessary modules
00060     keyListModule = check_and_cast<GiaKeyListModule*>
00061                     (parentModule()->submodule("keyListModule"));
00062     neighbors = check_and_cast<GiaNeighbors*>
00063                 (parentModule()->submodule("neighbors"));
00064     tokenFactory = check_and_cast<GiaTokenFactory*>
00065                    (parentModule()->submodule("tokenFactory"));
00066 
00067     msgBookkeepingList = new GiaMessageBookkeeping(neighbors, messageTimeout);
00068 
00069     // clear neighbor candidate list
00070     neighCand.clear();
00071     knownNodes.clear();
00072 
00073     WATCH(thisNode);
00074     WATCH(bootstrapNode);
00075     WATCH(levelOfSatisfaction);
00076 
00077     // self-messages
00078     satisfaction_timer = new cMessage("satisfaction_timer");
00079     update_timer = new cMessage("update_timer");
00080     timedoutMessages_timer = new cMessage("timedoutMessages_timer");
00081     timedoutNeighbors_timer = new cMessage("timedoutNeighbors_timer");
00082     sendKeyList_timer = new cMessage("sendKeyList_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 
00112     changeState(INIT);
00113     if(bootstrapNode.isUnspecified())
00114         changeState(OVERLAY_NOT_READY);
00115 }

void Gia::finishOverlay (  )  [virtual]

Writes statistical data and removes node from bootstrap oracle.

Reimplemented from BaseOverlay.

01159 {
01160     // statistics
01161 
01162         globalStatistics->addStdDev("GIA: JOIN-Messages Count", stat_joinCount);
01163     globalStatistics->addStdDev("GIA: JOIN Bytes sent", stat_joinBytesSent);
01164     globalStatistics->addStdDev("GIA: JOIN::REQ Messages", stat_joinREQ);
01165     globalStatistics->addStdDev("GIA: JOIN::REQ Bytes sent", stat_joinREQBytesSent);
01166     globalStatistics->addStdDev("GIA: JOIN::RSP Messages", stat_joinRSP);
01167     globalStatistics->addStdDev("GIA: JOIN::RSP Bytes sent", stat_joinRSPBytesSent);
01168     globalStatistics->addStdDev("GIA: JOIN::ACK Messages", stat_joinACK);
01169     globalStatistics->addStdDev("GIA: JOIN::ACK Bytes sent", stat_joinACKBytesSent);
01170     globalStatistics->addStdDev("GIA: JOIN::DNY Messages", stat_joinDNY);
01171     globalStatistics->addStdDev("GIA: JOIN::DNY Bytes sent", stat_joinDNYBytesSent);
01172     globalStatistics->addStdDev("GIA: DISCONNECT:IND Messages", stat_disconnectMessages);
01173     globalStatistics->addStdDev("GIA: DISCONNECT:IND Bytes sent",
01174                  stat_disconnectMessagesBytesSent);
01175     globalStatistics->addStdDev("GIA: UPDATE:IND Messages", stat_updateMessages);
01176     globalStatistics->addStdDev("GIA: UPDATE:IND Bytes sent", stat_updateMessagesBytesSent);
01177     globalStatistics->addStdDev("GIA: TOKEN:IND Messages", stat_tokenMessages);
01178     globalStatistics->addStdDev("GIA: TOKEN:IND Bytes sent", stat_tokenMessagesBytesSent);
01179     globalStatistics->addStdDev("GIA: KEYLIST:IND Messages", stat_keyListMessages);
01180     globalStatistics->addStdDev("GIA: KEYLIST:IND Bytes sent", stat_keyListMessagesBytesSent);
01181     globalStatistics->addStdDev("GIA: ROUTE:IND Messages", stat_routeMessages);
01182     globalStatistics->addStdDev("GIA: ROUTE:IND Bytes sent", stat_routeMessagesBytesSent);
01183     globalStatistics->addStdDev("GIA: Neighbors max", stat_maxNeighbors);
01184     globalStatistics->addStdDev("GIA: Neighbors added", stat_addedNeighbors);
01185     globalStatistics->addStdDev("GIA: Neighbors removed", stat_removedNeighbors);
01186     globalStatistics->addStdDev("GIA: Level of satisfaction messages ",
01187                  stat_numSatisfactionMessages);
01188     globalStatistics->addStdDev("GIA: Level of satisfaction max ",stat_maxLevelOfSatisfaction);
01189     globalStatistics->addStdDev("GIA: Level of satisfaction avg ",
01190                  stat_sumLevelOfSatisfaction / stat_numSatisfactionMessages);
01191     bootstrapOracle->removePeer(thisNode.getNodeHandle());
01192 }

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

Set state to toStage.

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

void Gia::setBootstrapedIcon (  )  [virtual]

Marks nodes if they are ready.

00215 {
00216     if (ev.isGUI()) {
00217         if (state == OVERLAY_READY) {
00218             parentModule()->parentModule()->displayString().
00219             setTagArg("i2", 1, "");
00220             displayString().setTagArg("i", 1, "");
00221         } else {
00222             parentModule()->parentModule()->displayString().
00223             setTagArg("i2", 1, "red");
00224             displayString().setTagArg("i", 1, "red");
00225         }
00226     }
00227 }

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

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented from BaseOverlay.

00230 {
00231     if (msg->isName("satisfaction_timer")) {
00232         // calculate level of satisfaction and select new neighbor candidate
00233 
00234         levelOfSatisfaction = calculateLevelOfSatisfaction();
00235         stat_numSatisfactionMessages++;
00236         stat_sumLevelOfSatisfaction += levelOfSatisfaction;
00237         if (levelOfSatisfaction > stat_maxLevelOfSatisfaction)
00238             stat_maxLevelOfSatisfaction = levelOfSatisfaction;
00239 
00240         // start again satisfaction_timer
00241         scheduleAt(simulation.simTime() + (maxTopAdaptionInterval *
00242                                            pow(topAdaptionAggressiveness,
00243                                                -(1 - levelOfSatisfaction))),
00244                    satisfaction_timer);
00245 
00246         // Only search a new neighbor if level of satisfaction is
00247         // under level of maxLevelOfSatisfaction
00248         if(levelOfSatisfaction < maxLevelOfSatisfaction) {
00249             if(knownNodes.getSize() == 0)
00250                 if(neighbors->getSize() == 0 && neighCand.getSize() == 0)
00251                     knownNodes.add(bootstrapOracle->getBootstrapNode());
00252                 else
00253                     return;
00254 
00255             NodeHandle possibleNeighbor = knownNodes.getRandomCandidate();
00256 
00257             if(!(possibleNeighbor.isUnspecified()) &&
00258                     thisNode.getNodeHandle() != possibleNeighbor &&
00259                     !neighbors->contains(possibleNeighbor) &&
00260                     !neighCand.contains(possibleNeighbor)) {
00261                 // try to add new neighbor
00262                 neighCand.add(possibleNeighbor);
00263                 sendMessage_JOIN_REQ(possibleNeighbor);
00264             }
00265         }
00266     } else if (msg->isName("update_timer")) {
00267         // send current capacity and degree to all neighbors
00268         for (uint i=0; i<neighbors->getSize(); i++) {
00269             sendMessage_UPDATE(neighbors->get(i));
00270         }
00271     } else if (msg->isName("timedoutMessages_timer")) {
00272         // remove timedout messages
00273         msgBookkeepingList->removeTimedoutMessages();
00274         scheduleAt(simulation.simTime() + messageTimeout,
00275                    timedoutMessages_timer);
00276     } else if (msg->isName("timedoutNeighbors_timer")) {
00277         // remove timedout neighbors
00278         neighbors->removeTimedoutNodes();
00279         if (neighbors->getSize() == 0) {
00280             changeState(OVERLAY_NOT_READY);
00281             changeState(INIT);
00282         }
00283         cancelEvent(timedoutNeighbors_timer);
00284         scheduleAt(simulation.simTime() + neighborTimeout,
00285                    timedoutNeighbors_timer);
00286     } else if (msg->isName("sendKeyList_timer")) {
00287         if (keyList.getSize() > 0) {
00288             // send keyList to all of our neighbors
00289             for (uint i=0; i<neighbors->getSize(); i++)
00290                 sendKeyListToNeighbor(neighbors->get(i));
00291         }
00292     } else {
00293         // other self-messages are notoken-self-messages
00294         // with an encapsulated message
00295         const std::string id = msg->name();
00296         if (id.substr(0, 16) == std::string("wait-for-token: ")) {
00297             cMessage* decapsulatedMessage = msg->decapsulate();
00298             if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00299                 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00300                                         (decapsulatedMessage);
00301                 forwardMessage(message, false);
00302             }
00303         } else if (id.substr(0, 24) == std::string("wait-for-token-fromapp: ")) {
00304             cMessage* decapsulatedMessage = msg->decapsulate();
00305             if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00306                 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00307                                         (decapsulatedMessage);
00308                 forwardMessage(message, true);
00309             }
00310         }
00311         delete msg;
00312     }
00313 }

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

Processes messages from underlay.

Parameters:
msg Message from UDP

Implements BaseOverlay.

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

void Gia::route ( const OverlayKey key,
cMessage *  msg,
const NodeHandle hint = NodeHandle::UNSPECIFIED_NODE 
) [virtual]

Route msg received from application layer to node with ID key.

Parameters:
key Node-ID
msg Message to route
hint next hop (usually not used)

Reimplemented from BaseOverlay.

00962 {
00963     if (state == OVERLAY_READY) {
00964         GiaRouteMessage* routeMsg = new GiaRouteMessage("ROUTE");
00965         routeMsg->setSignaling(false);
00966         routeMsg->setCommand(ROUTE);
00967         routeMsg->setHopCount(maxHopCount);
00968         routeMsg->setDestKey(key);
00969         routeMsg->setSrcNode(thisNode.getNodeHandle());
00970         routeMsg->setSrcCapacity(thisNode.getCapacity());
00971         routeMsg->setSrcDegree(thisNode.getConnectionDegree());
00972         routeMsg->setOriginatorKey(thisNode.getNodeHandle().key);
00973         routeMsg->setOriginatorIP(thisNode.getNodeHandle().ip);
00974         routeMsg->setOriginatorPort(thisNode.getNodeHandle().port);
00975         routeMsg->setID(OverlayKey::random());
00976         routeMsg->setLength(GIAROUTE_L(routeMsg));
00977         routeMsg->encapsulate(msg);
00978 
00979 
00980         forwardMessage(routeMsg, true);
00981     } else {
00982         RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
00983         delete msg;
00984     }
00985 }

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

Processes non-commonAPI messages.


Processes non-commonAPI messages if parameter "onlyCommonAPIMessages" is false.

Parameters:
msg non-commonAPIMessage

Reimplemented from BaseOverlay.

00988 {
00989     // do we receive a keylist?
00990     if (dynamic_cast<GIAput*>(msg) != NULL) {
00991         GIAput* putMsg = check_and_cast<GIAput*>(msg);
00992         uint keyListSize = putMsg->getKeysArraySize();
00993         for (uint k=0; k<keyListSize; k++)
00994             keyList.addKeyItem(putMsg->getKeys(k));
00995 
00996         // actualize vector in KeyListModule
00997         keyListModule->setKeyListVector(keyList.getVector());
00998 
00999         scheduleAt(simulation.simTime() + keyListDelay, sendKeyList_timer);
01000 
01001         delete putMsg;
01002     } else if (dynamic_cast<GIAsearch*>(msg) != NULL) {
01003         if (state == OVERLAY_READY) {
01004             GIAsearch* getMsg = check_and_cast<GIAsearch*>(msg);
01005             SearchMessage* searchMsg = new SearchMessage("SEARCH");
01006             searchMsg->setCommand(SEARCH);
01007             searchMsg->setSignaling(false);
01008             searchMsg->setHopCount(maxHopCount);
01009             searchMsg->setDestKey(getMsg->getSearchKey());
01010             searchMsg->setSrcNode(thisNode.getNodeHandle());
01011             searchMsg->setSrcCapacity(thisNode.getCapacity());
01012             searchMsg->setSrcDegree(thisNode.getConnectionDegree());
01013             searchMsg->setSearchKey(getMsg->getSearchKey());
01014             searchMsg->setMaxResponses(getMsg->getMaxResponses());
01015             searchMsg->setReversePathArraySize(0);
01016             searchMsg->setID(OverlayKey::random());
01017             searchMsg->setLength(SEARCH_L(searchMsg));
01018 
01019             processSearchMessage(searchMsg, true);
01020 
01021             delete getMsg;
01022         } else
01023             delete msg;
01024     } else {
01025         delete msg;
01026         EV << "(Gia) unkown message from app deleted!" << endl;
01027     }
01028 }

void Gia::sendToken ( const GiaNode dst  ) 

00761 {
00762     TokenMessage* tokenMsg = new TokenMessage("TOKEN");
00763     tokenMsg->setCommand(TOKEN);
00764     tokenMsg->setHopCount(maxHopCount);
00765     tokenMsg->setSrcNode(thisNode.getNodeHandle());
00766     tokenMsg->setSrcCapacity(thisNode.getCapacity());
00767     tokenMsg->setSrcDegree(thisNode.getConnectionDegree());
00768     tokenMsg->setSrcTokenNr(dst.getReceivedTokens());
00769     tokenMsg->setDstTokenNr(dst.getSentTokens()+1);
00770     tokenMsg->setLength(TOKEN_L(tokenMsg));
00771 
00772     stat_tokenMessagesBytesSent += tokenMsg->byteLength();
00773     stat_tokenMessages += 1;
00774 
00775     sendMessageToUDP(dst.getNodeHandle(), tokenMsg);
00776 }

bool Gia::acceptNode ( const GiaNode newNode  )  [protected]

Decides if Node newNode will be accepted as new neighor.

Parameters:
newNode Node to accept or deny
Returns:
boolean true or false
00530 {
00531     if (neighbors->contains(nNode.getNodeHandle()))
00532         return false;
00533 
00534     if (neighbors->getSize() < maxNeighbors) {
00535         // we have room for new node: accept node
00536         return true;
00537     }
00538     // we need to drop a neighbor
00539     NodeHandle dropCandidate = neighbors->getDropCandidate(nNode.getCapacity(), nNode.getConnectionDegree());
00540     if(!dropCandidate.isUnspecified()) {
00541         if (debugOutput)
00542             EV << "(Gia) " << thisNode << " drops "
00543                << dropCandidate <<  endl;
00544         neighbors->remove(dropCandidate);
00545         sendMessage_DISCONNECT(dropCandidate);
00546         return true;
00547     }       
00548     return false;
00549 }

void Gia::addNeighbor ( GiaNode newNode  )  [protected]

Adds newNode as new neighbor.

Parameters:
newNode 
00553 {
00554     assert(neighbors->getSize() < maxNeighbors);
00555 
00556     stat_addedNeighbors++;
00557     EV << "(Gia) " << thisNode << " accepted new neighbor " << node << endl;
00558     parentModule()->parentModule()->bubble("New neighbor");
00559     thisNode.setConnectionDegree(neighbors->getSize());
00560     changeState(OVERLAY_READY);
00561     if (stat_maxNeighbors < neighbors->getSize()) {
00562         stat_maxNeighbors = neighbors->getSize();
00563     }
00564 
00565     cancelEvent(update_timer);
00566     scheduleAt(simulation.simTime() + updateDelay, update_timer);
00567 
00568     node.setSentTokens(5);
00569     node.setReceivedTokens(5);
00570 
00571     // send keyList to new Neighbor
00572     if (keyList.getSize() > 0)
00573         sendKeyListToNeighbor(node);
00574     neighbors->add(node);
00575 
00576     showOverlayNeighborArrow(node.getNodeHandle(), false,
00577                              "m=m,50,0,50,0;o=red,1");
00578 }

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

Removes newNode from our NeighborList.

Parameters:
newNode 
00581 {
00582     stat_removedNeighbors++;
00583 
00584     if (debugOutput)
00585         EV << "(Gia) " << thisNode << " removes " << node
00586            << " from neighborlist." << endl;
00587     neighbors->remove(node);
00588 
00589     thisNode.setConnectionDegree(neighbors->getSize());
00590 
00591     if (neighbors->getSize() == 0) {
00592         changeState(OVERLAY_NOT_READY);
00593         changeState(INIT);
00594     }
00595 
00596     deleteOverlayNeighborArrow(node);
00597 
00598     cancelEvent(update_timer);
00599     scheduleAt(simulation.simTime() + updateDelay, update_timer);
00600 }

double Gia::calculateLevelOfSatisfaction (  )  [protected]

Calculates level of satisfaction.

Returns:
levelOfSatisfaction value
00603 {
00604     uint neighborsCount = neighbors->getSize();
00605     if(neighborsCount < minNeighbors)
00606         return 0.0;
00607 
00608     double total = 0.0;
00609     double levelOfSatisfaction = 0.0;
00610 
00611     for (uint i=0; i < neighborsCount; i++)
00612         total += neighbors->get(neighbors->get(i))->capacity / neighborsCount;
00613 
00614     assert(thisNode.getCapacity() != 0);
00615     levelOfSatisfaction = total / thisNode.getCapacity();
00616 
00617     if ((levelOfSatisfaction > 1.0) || (neighborsCount >= maxNeighbors))
00618         return 1.0;
00619     return levelOfSatisfaction;
00620 }

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

Sends JOIN_REQ_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00624 {
00625     // send JOIN:REQ message
00626     GiaMessage* msg = new GiaMessage("JOIN_REQ");
00627     msg->setCommand(JOIN_REQUEST);
00628     msg->setSrcNode(thisNode.getNodeHandle());
00629     msg->setSrcCapacity(thisNode.getCapacity());
00630     msg->setSrcDegree(thisNode.getConnectionDegree());
00631     msg->setLength(GIA_L(msg));
00632 
00633     stat_joinCount += 1;
00634     stat_joinBytesSent += msg->byteLength();
00635     stat_joinREQ += 1;
00636     stat_joinREQBytesSent += msg->byteLength();
00637 
00638     sendMessageToUDP(dst, msg);
00639 }

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

Sends JOIN_RSP_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00642 {
00643     // send JOIN:RSP message
00644     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_RSP");
00645     msg->setCommand(JOIN_RESPONSE);
00646     msg->setSrcNode(thisNode.getNodeHandle());
00647     msg->setSrcCapacity(thisNode.getCapacity());
00648     msg->setSrcDegree(thisNode.getConnectionDegree());
00649 
00650     msg->setNeighborsArraySize(neighbors->getSize());
00651     //TODO: add parameter maxSendNeighbors
00652     for(uint i = 0; i < neighbors->getSize(); i++)
00653         msg->setNeighbors(i, neighbors->get(i));
00654 
00655     msg->setLength(GIANEIGHBOR_L(msg));
00656 
00657     stat_joinCount += 1;
00658     stat_joinBytesSent += msg->byteLength();
00659     stat_joinRSP += 1;
00660     stat_joinRSPBytesSent += msg->byteLength();
00661 
00662     sendMessageToUDP(dst, msg);
00663 }

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

Sends JOIN_ACK_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00666 {
00667     // send JOIN:ACK message
00668     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_ACK");
00669     msg->setCommand(JOIN_ACK);
00670     msg->setSrcNode(thisNode.getNodeHandle());
00671     msg->setSrcCapacity(thisNode.getCapacity());
00672     msg->setSrcDegree(thisNode.getConnectionDegree());
00673 
00674     msg->setNeighborsArraySize(neighbors->getSize());
00675     //TODO: add parameter maxSendNeighbors
00676     for(uint i = 0; i < neighbors->getSize(); i++)
00677         msg->setNeighbors(i, neighbors->get(i));
00678 
00679     msg->setLength(GIANEIGHBOR_L(msg));
00680 
00681     stat_joinCount += 1;
00682     stat_joinBytesSent += msg->byteLength();
00683     stat_joinACK += 1;
00684     stat_joinACKBytesSent += msg->byteLength();
00685 
00686     sendMessageToUDP(dst, msg);
00687 }

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

Sends JOIN_DNY_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00690 {
00691     // send JOIN:DNY message
00692     GiaMessage* msg = new GiaMessage("JOIN_DENY");
00693     msg->setCommand(JOIN_DENY);
00694     msg->setSrcNode(thisNode.getNodeHandle());
00695     msg->setSrcCapacity(thisNode.getCapacity());
00696     msg->setSrcDegree(thisNode.getConnectionDegree());
00697     msg->setLength(GIA_L(msg));
00698 
00699     stat_joinCount += 1;
00700     stat_joinBytesSent += msg->byteLength();
00701     stat_joinDNY += 1;
00702     stat_joinDNYBytesSent += msg->byteLength();
00703 
00704     sendMessageToUDP(dst, msg);
00705 }

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

Sends DISCONNECT_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00708 {
00709     // send DISCONNECT:IND message
00710     GiaMessage* msg = new GiaMessage("DISCONNECT");
00711     msg->setCommand(DISCONNECT);
00712     msg->setSrcNode(thisNode.getNodeHandle());
00713     msg->setSrcCapacity(thisNode.getCapacity());
00714     msg->setSrcDegree(thisNode.getConnectionDegree());
00715     msg->setLength(GIA_L(msg));
00716 
00717     stat_disconnectMessagesBytesSent += msg->byteLength();
00718     stat_disconnectMessages += 1;
00719 
00720     sendMessageToUDP(dst, msg);
00721 }

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

Sends UPDATE_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00724 {
00725     // send UPDATE:IND message
00726     GiaMessage* msg = new GiaMessage("UPDATE");
00727     msg->setCommand(UPDATE);
00728     msg->setSrcNode(thisNode.getNodeHandle());
00729     msg->setSrcCapacity(thisNode.getCapacity());
00730     msg->setSrcDegree(thisNode.getConnectionDegree());
00731     msg->setLength(GIA_L(msg));
00732 
00733     stat_updateMessagesBytesSent += msg->byteLength();
00734     stat_updateMessages += 1;
00735 
00736     sendMessageToUDP(dst, msg);
00737 }

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

Sends KeyList to node dst.

Parameters:
dst,: Destination
00740 {
00741     // send KEYLIST:IND message
00742     KeyListMessage* msg = new KeyListMessage("KEYLIST");
00743     msg->setCommand(KEYLIST);
00744     msg->setSrcNode(thisNode.getNodeHandle());
00745     msg->setSrcCapacity(thisNode.getCapacity());
00746     msg->setSrcDegree(thisNode.getConnectionDegree());
00747 
00748     msg->setKeysArraySize(keyList.getSize());
00749     for (uint i=0; i<keyList.getSize(); i++)
00750         msg->setKeys(i, keyList.get(i));
00751 
00752     msg->setLength(KEYLIST_L(msg));
00753 
00754     stat_keyListMessagesBytesSent += msg->byteLength();
00755     stat_keyListMessages += 1;
00756 
00757     sendMessageToUDP(dst.getNodeHandle(), msg);
00758 }

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

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

Parameters:
msg Received message
00779 {
00780     if(neighbors->contains(msg->getSrcNode().key)) {
00781         neighbors->setConnectionDegree(msg->getSrcNode(),msg->getSrcDegree());
00782         neighbors->setCapacity(msg->getSrcNode(), msg->getSrcCapacity());
00783         neighbors->updateTimestamp(msg->getSrcNode());
00784     }
00785 }

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
00788 {
00789     if (responseMsg->getHopCount() != 0) {
00790         uint reversePathArraySize = responseMsg->getReversePathArraySize();
00791 
00792         // reached node which started search?
00793         if (reversePathArraySize == 0) {
00794             deliverSearchResult(responseMsg);
00795         }
00796         // forward message to next node in reverse path list
00797         else {
00798             NodeHandle targetNode = neighbors->get
00799                                   (responseMsg->getReversePath(
00800                                        reversePathArraySize-1));
00801 
00802             if(!(targetNode.isUnspecified())) {
00803                 responseMsg->setDestKey(targetNode.key);
00804                 responseMsg->setReversePathArraySize(reversePathArraySize-1);
00805                 for (uint i=0; i<reversePathArraySize-1; i++)
00806                     responseMsg->setReversePath(i, responseMsg->getReversePath(i));
00807                 responseMsg->setLength(responseMsg->length() - KEY_L);
00808 
00809                 stat_routeMessagesBytesSent += responseMsg->byteLength();
00810                 stat_routeMessages += 1;
00811 
00812                 if(responseMsg->getHopCount() > 0)
00813                     RECORD_STATS(numForwarded++; bytesForwarded +=
00814                                      responseMsg->byteLength());
00815 
00816                 sendMessageToUDP(targetNode, responseMsg);
00817             } else {
00818                 EV << "(Gia) wrong reverse path in " << *responseMsg
00819                    << " ... deleted!" << endl;
00820                 RECORD_STATS(numDropped++;
00821                              bytesDropped += responseMsg->byteLength());
00822                 delete responseMsg;
00823             }
00824         }
00825     }
00826     // max hopcount reached. delete message
00827     else
00828         delete responseMsg;
00829 }

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
00832 {
00833     if (msg->getHopCount() == 0) {
00834         // Max-Hopcount reached. Discard message
00835         if (!fromApplication)
00836             tokenFactory->grantToken();
00837         RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
00838         delete msg;
00839     } else {
00840         // local delivery?
00841         if (msg->getDestKey() == thisNode.getNodeHandle().key) {
00842             if(!fromApplication)
00843                 tokenFactory->grantToken();
00844 
00845             if(debugOutput)
00846                 EV << "(Gia) Deliver messsage " << msg
00847                 << " to application at " << thisNode << endl;
00848 
00849             OverlayCtrlInfo* overlayCtrlInfo =
00850                 new OverlayCtrlInfo();
00851 
00852             overlayCtrlInfo->setHopCount(msg->getHopCount());
00853             overlayCtrlInfo->setSrcNode(msg->getSrcNode());
00854 
00855             msg->setControlInfo(overlayCtrlInfo);
00856             callDeliver(msg, msg->getDestKey());
00857         } else {
00858             // forward message to next hop
00859 
00860             // do we know the destination-node?
00861             if (neighbors->contains(msg->getDestKey())) {
00862                 // yes, destination-Node is our neighbor
00863                 NodeHandle targetNode = neighbors->get(msg->getDestKey());
00864                 GiaNeighborInfo* targetInfo= neighbors->get(targetNode);
00865 
00866                 if (targetInfo->receivedTokens == 0) {
00867                     // wait for free token
00868                     if (debugOutput)
00869                         EV << "(Gia) No free Node, wait for free token" << endl;
00870 
00871                     //bad code
00872                     std::string id;
00873                     if (!fromApplication)
00874                         id = "wait-for-token: " + msg->getID().toString();
00875                     else
00876                         id = "wait-for-token-fromapp: " +
00877                              msg->getID().toString();
00878                     cMessage* wait_timer = new cMessage(id.c_str());
00879                     wait_timer->encapsulate(msg);
00880                     scheduleAt(simulation.simTime() + tokenWaitTime,wait_timer);
00881                     return;
00882                 } else {
00883                     // decrease nextHop-tokencount
00884                     targetInfo->receivedTokens = targetInfo->receivedTokens - 1;
00885 
00886                     // forward msg to nextHop
00887                     msg->setHopCount(msg->getHopCount()-1);
00888                     msg->setSrcNode(thisNode.getNodeHandle());
00889                     msg->setSrcCapacity(thisNode.getCapacity());
00890                     msg->setSrcDegree(thisNode.getConnectionDegree());
00891                     if (debugOutput)
00892                         EV << "(Gia) Forwarding message " << msg
00893                         << " to neighbor " << targetNode << endl;
00894                     if (!fromApplication)
00895                         tokenFactory->grantToken();
00896 
00897                     stat_routeMessagesBytesSent += msg->byteLength();
00898                     stat_routeMessages += 1;
00899 
00900                     if(msg->getHopCount() > 0)
00901                         RECORD_STATS(numForwarded++; bytesForwarded +=
00902                                          msg->byteLength());
00903 
00904                     sendMessageToUDP(targetNode, msg);
00905                 }
00906             } else {
00907                 // no => pick node with at least one token and highest capacity
00908                 if (!msgBookkeepingList->contains(msg))
00909                     msgBookkeepingList->addMessage(msg);
00910                 NodeHandle nextHop = msgBookkeepingList->getNextHop(msg);
00911 
00912                 // do we have a neighbor who send us a token?
00913                 if(nextHop.isUnspecified()) {
00914                     // wait for free token
00915                     if (debugOutput)
00916                         EV << "(Gia) No free Node, wait for free token" << endl;
00917                     std::string id;
00918                     if (!fromApplication)
00919                         id = "wait-for-token: " + msg->getID().toString();
00920                     else
00921                         id = "wait-for-token-fromapp: " +
00922                              msg->getID().toString();
00923                     cMessage* wait_timer = new cMessage(id.c_str());
00924                     wait_timer->encapsulate(msg);
00925                     scheduleAt(simulation.simTime() + tokenWaitTime,wait_timer);
00926                     return;
00927                 } else {
00928                     GiaNeighborInfo* nextHopInfo = neighbors->get(nextHop);
00929                     if(nextHopInfo == NULL) {
00930                         delete msg;
00931                         return; //???
00932                     }
00933                     // decrease nextHop-tokencount
00934                     nextHopInfo->receivedTokens--;
00935 
00936                     // forward msg to nextHop
00937                     msg->setHopCount(msg->getHopCount()-1);
00938                     msg->setSrcNode(thisNode.getNodeHandle());
00939                     msg->setSrcCapacity(thisNode.getCapacity());
00940                     msg->setSrcDegree(thisNode.getConnectionDegree());
00941                     if (debugOutput)
00942                         EV << "(Gia) Forwarding message " << msg
00943                         << " to " << nextHop << endl;
00944                     if (!fromApplication)
00945                         tokenFactory->grantToken();
00946 
00947                     stat_routeMessagesBytesSent += msg->byteLength();
00948                     stat_routeMessages += 1;
00949 
00950                     if(msg->getHopCount() > 0)
00951                         RECORD_STATS(numForwarded++; bytesForwarded +=
00952                                          msg->byteLength());
00953 
00954                     sendMessageToUDP(nextHop, msg);
00955                 }
00956             }
00957         }
00958     }
00959 }

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
01095 {
01096     OverlayKey searchKey = msg->getSearchKey();
01097 
01098     if (keyList.contains(searchKey)) {
01099         // this node contains search key
01100         sendSearchResponseMessage(thisNode, msg);
01101     }
01102 
01103     // check if neighbors contain search key
01104     for (uint i = 0; i < neighbors->getSize(); i++) {
01105         GiaKeyList* keyList = neighbors->getNeighborKeyList(neighbors->get(i));
01106         if (keyList->contains(searchKey))
01107             sendSearchResponseMessage(neighbors->get(i), msg);
01108     }
01109 
01110     // forward search-message to next hop
01111     if (msg->getMaxResponses() > 0) {
01112         // actualize reverse path
01113         uint reversePathSize = msg->getReversePathArraySize();
01114 
01115         if (optimizeReversePath)
01116             for (uint i=0; i<reversePathSize; i++) {
01117                 if (msg->getReversePath(i) == thisNode.getNodeHandle().key) {
01118                     // Our node already in ReversePath.
01119                     // Delete successor nodes from ReversePath
01120                     msg->setLength(msg->length() - (reversePathSize - i)*KEY_L);
01121                     reversePathSize = i; // set new array size
01122                     break;
01123                 }
01124             }
01125 
01126         msg->setReversePathArraySize(reversePathSize+1);
01127         msg->setReversePath(reversePathSize, thisNode.getNodeHandle().key);
01128         msg->setLength(msg->length() + KEY_L);
01129 
01130         forwardMessage(msg, fromApplication);
01131     } else {
01132         tokenFactory->grantToken();
01133         delete msg;
01134     }
01135 }

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
01032 {
01033     // does SearchMessage->foundNode[] already contain this node
01034     uint foundNodeArraySize = msg->getFoundNodeArraySize();
01035     bool containsNode = false;
01036     for (uint i=0; i<foundNodeArraySize; i++)
01037         if (srcNode.getNodeHandle().key == msg->getFoundNode(i))
01038             containsNode = true;
01039 
01040     if (!containsNode && msg->getMaxResponses() > 0) {
01041         // add this node to SearchMessage->foundNode[]
01042         msg->setFoundNodeArraySize(foundNodeArraySize+1);
01043         msg->setFoundNode(foundNodeArraySize, srcNode.getNodeHandle().key);
01044 
01045         // decrease SearchMessage->maxResponses
01046         msg->setMaxResponses(msg->getMaxResponses()-1);
01047 
01048         // get first node in reverse-path
01049         uint reversePathArraySize = msg->getReversePathArraySize();
01050 
01051         if (reversePathArraySize == 0) {
01052             // we have the key
01053             // deliver response to application
01054             SearchResponseMessage* responseMsg =
01055                 new SearchResponseMessage("ANSWER");
01056             responseMsg->setCommand(ANSWER);
01057             responseMsg->setSignaling(false);
01058             responseMsg->setHopCount(maxHopCount);
01059             responseMsg->setSrcNode(thisNode.getNodeHandle());
01060             responseMsg->setSrcCapacity(thisNode.getCapacity());
01061             responseMsg->setSrcDegree(thisNode.getConnectionDegree());
01062             responseMsg->setSearchKey(msg->getSearchKey());
01063             responseMsg->setFoundNode(srcNode);
01064             responseMsg->setID(OverlayKey::random());
01065             responseMsg->setSearchHopCount(0);
01066 
01067             responseMsg->setLength(SEARCHRESPONSE_L(responseMsg));
01068 
01069             deliverSearchResult(responseMsg);
01070         } else {
01071             uint reversePathArraySize(msg->getReversePathArraySize());
01072             SearchResponseMessage* responseMsg =
01073                 new SearchResponseMessage("ANSWER");
01074             responseMsg->setCommand(ANSWER);
01075             responseMsg->setHopCount(maxHopCount);
01076             responseMsg->setSrcNode(srcNode.getNodeHandle());
01077             responseMsg->setSrcCapacity(srcNode.getCapacity());
01078             responseMsg->setSrcDegree(srcNode.getConnectionDegree());
01079             responseMsg->setSearchKey(msg->getSearchKey());
01080             responseMsg->setFoundNode(srcNode);
01081             responseMsg->setReversePathArraySize(reversePathArraySize);
01082             for (uint i=0; i<reversePathArraySize; i++)
01083                 responseMsg->setReversePath(i, msg->getReversePath(i));
01084             responseMsg->setID(OverlayKey::random());
01085             responseMsg->setSearchHopCount(reversePathArraySize);
01086             responseMsg->setLength(SEARCHRESPONSE_L(responseMsg));
01087 
01088             forwardSearchResponseMessage(responseMsg);
01089         }
01090     }
01091 }

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

Delivers search result to application layer.

Parameters:
msg Search response message
01138 {
01139     OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo();
01140     overlayCtrlInfo->setHopCount(msg->getSearchHopCount());
01141     overlayCtrlInfo->setSrcNode(msg->getSrcNode());
01142 
01143     GIAanswer* deliverMsg = new GIAanswer("GIA-Answer");
01144     deliverMsg->setCommand(GIA_ANSWER);
01145     deliverMsg->setControlInfo(overlayCtrlInfo);
01146     deliverMsg->setSearchKey(msg->getSearchKey());
01147     deliverMsg->setNode(msg->getFoundNode().getNodeHandle());
01148     deliverMsg->setLength(GIAGETRSP_L(msg));
01149 
01150     send(deliverMsg, "to_app");
01151     if (debugOutput)
01152         EV << "(Gia) Deliver search response " << msg
01153         << " to application at " << thisNode << endl;
01154 
01155     delete msg;
01156 }


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::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?

int Gia::state [protected]

current state of this node (initialization, overlay (not) ready)

double Gia::levelOfSatisfaction [protected]

current level of statisfaction

GiaNode Gia::thisNode [protected]

this node

Reimplemented from BaseRpc.

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

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 Tue Jul 24 16:51:18 2007 for ITM OverSim by  doxygen 1.5.1