Gia Class Reference

#include <Gia.h>

Inheritance diagram for Gia:

BaseOverlay 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)
 Sends messages to UDP and collects statistical data.
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 GiaNode &newNode)
 Removes newNode from our NeighborList.
double calculateLevelOfSatisfaction ()
 Calculates level of satisfaction.
void sendMessage_JOIN_REQ (const GiaNode &src, const NodeHandle &dst)
 Sends JOIN_REQ_Message from node src to node dst.
void sendMessage_JOIN_RSP (const GiaNode &src, const NodeHandle &dst)
 Sends JOIN_RSP_Message from node src to node dst.
void sendMessage_JOIN_ACK (const GiaNode &src, const NodeHandle &dst)
 Sends JOIN_ACK_Message from node src to node dst.
void sendMessage_JOIN_DNY (const GiaNode &src, const NodeHandle &dst)
 Sends JOIN_DNY_Message from node src to node dst.
void sendMessage_DISCONNECT (const GiaNode &src, const NodeHandle &dst)
 Sends DISCONNECT_Message from node src to node dst.
void sendMessage_UPDATE (const GiaNode &src, 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
MessageBookkeepingmsgBookkeepingList
 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
KeyListModulekeyListModule
 pointer to KeyListModule
Neighborsneighbors
 pointer to neighbor list
TokenFactorytokenFactory
 pointer to TokenFactory
NeighborCandidateList neighCand
 list of all neighbor candidates
NeighborCandidateList knownNodes
 list of known nodes in the overlay
KeyList keyList
 key list of this node


Constructor & Destructor Documentation

Gia::~Gia (  ) 

Destructor.

01249 {
01250     cancelAndDelete(satisfaction_timer);
01251     cancelAndDelete(update_timer);
01252     cancelAndDelete(timedoutMessages_timer);
01253     cancelAndDelete(timedoutNeighbors_timer);
01254     cancelAndDelete(sendKeyList_timer);
01255     delete msgBookkeepingList;
01256 }


Member Function Documentation

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
00553 {
00554     if (neighbors->contains(nNode))
00555         return false;
00556 
00557     if (neighbors->getSize() < maxNeighbors) {
00558         // we have room for new node: accept node
00559         return true;
00560     }
00561     // we need to drop a neighbor
00562     else {
00563         // determine node with highest capacity
00564         std::vector<GiaNode> dropCandidateList;
00565         double maxCapacity = 0;
00566         GiaNode dropCandidate;
00567         for (uint i=0; i<neighbors->getSize(); i++) {
00568             if (neighbors->get
00569                     (i)->getCapacity() <= nNode.getCapacity()) {
00570                 dropCandidateList.push_back(*(neighbors->get
00571                                               (i)));
00572                 if (neighbors->get
00573                         (i)->getCapacity() > maxCapacity) {
00574                     dropCandidate = *(neighbors->get
00575                                       (i));
00576                     maxCapacity = dropCandidate.getCapacity();
00577                 }
00578             }
00579         }
00580 
00581         // has nNode lower capacity than all of our neighbors?
00582         if (dropCandidateList.size() == 0)
00583             return false;
00584         else {
00585             if((dropCandidateList.size() == neighbors->getSize()
00586                     || dropCandidate.getConnectionDegree() >
00587                     nNode.getConnectionDegree())
00588                     && dropCandidate.getConnectionDegree() > 1) {
00589                 if (debugOutput)
00590                     EV << "(Gia) " << thisNode << " drops "
00591                     << dropCandidate << " in favor of " << nNode << endl;
00592                 removeNeighbor(dropCandidate);
00593                 sendMessage_DISCONNECT(thisNode, dropCandidate.getNodeHandle());
00594                 return true;
00595             } else
00596                 return false;
00597         }
00598     }
00599     return false;
00600 }

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

Adds newNode as new neighbor.

Parameters:
newNode 
00603 {
00604     assert(neighbors->getSize() < maxNeighbors);
00605 
00606     stat_addedNeighbors++;
00607     EV << "(Gia) " << thisNode << " accepted new neighbor " << node << endl;
00608     parentModule()->parentModule()->bubble("New neighbor");
00609     thisNode.setConnectionDegree(neighbors->getSize());
00610     changeState(OVERLAY_READY);
00611     if (stat_maxNeighbors < neighbors->getSize()) {
00612         stat_maxNeighbors = neighbors->getSize();
00613     }
00614 
00615     cancelEvent(update_timer);
00616     scheduleAt(simulation.simTime() + updateDelay, update_timer);
00617 
00618     node.setSentTokens(5);
00619     node.setReceivedTokens(5);
00620 
00621     // send keyList to new Neighbor
00622     if (keyList.getSize() > 0)
00623         sendKeyListToNeighbor(node);
00624     neighbors->add
00625     (node);
00626 
00627     showOverlayNeighborArrow(node.getNodeHandle(), false,
00628                              "m=m,50,0,50,0;o=red,1");
00629     bootstrapOracle->registerPeer(thisNode.getNodeHandle());
00630 }

double Gia::calculateLevelOfSatisfaction (  )  [protected]

Calculates level of satisfaction.

Returns:
levelOfSatisfaction value
00654 {
00655     uint neighborsCount = neighbors->getSize();
00656     if(neighborsCount < minNeighbors)
00657         return 0.0;
00658 
00659     double total = 0.0;
00660     double levelOfSatisfaction = 0.0;
00661 
00662     for (uint i=0; i < neighborsCount; i++)
00663         total += neighbors->get
00664                  (i)->getCapacity() / neighborsCount;
00665 
00666     assert(thisNode.getCapacity() != 0);
00667     levelOfSatisfaction = total / thisNode.getCapacity();
00668 
00669     if ((levelOfSatisfaction > 1.0) || (neighborsCount >= maxNeighbors))
00670         return 1.0;
00671     return levelOfSatisfaction;
00672 }

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

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

Delivers search result to application layer.

Parameters:
msg Search response message
01193 {
01194     OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo();
01195     overlayCtrlInfo->setHopCount(msg->getSearchHopCount());
01196     overlayCtrlInfo->setSrcNode(msg->getSrcNode());
01197 
01198     GIAanswer* deliverMsg = new GIAanswer("GIA-Answer");
01199     deliverMsg->setCommand(GIA_ANSWER);
01200     deliverMsg->setControlInfo(overlayCtrlInfo);
01201     deliverMsg->setSearchKey(msg->getSearchKey());
01202     deliverMsg->setNode(msg->getFoundNode().getNodeHandle());
01203     deliverMsg->setLength(GIAGETRSP_L(msg));
01204 
01205     send(deliverMsg, "to_app");
01206     if (debugOutput)
01207         EV << "(Gia) Deliver search response " << msg
01208         << " to application at " << thisNode << endl;
01209 
01210     delete msg;
01211 }

void Gia::finishOverlay (  )  [virtual]

Writes statistical data and removes node from bootstrap oracle.

Reimplemented from BaseOverlay.

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

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
00890 {
00891     if (msg->getHopCount() == 0) {
00892         // Max-Hopcount reached. Discard message
00893         if (!fromApplication)
00894             tokenFactory->grantToken();
00895         RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
00896         delete msg;
00897     } else {
00898         // local delivery?
00899         if (msg->getDestKey() == thisNode.getNodeHandle().key) {
00900             if(!fromApplication)
00901                 tokenFactory->grantToken();
00902 
00903             if(debugOutput)
00904                 EV << "(Gia) Deliver messsage " << msg
00905                 << " to application at " << thisNode << endl;
00906 
00907             OverlayCtrlInfo* overlayCtrlInfo =
00908                 new OverlayCtrlInfo();
00909 
00910             overlayCtrlInfo->setThisNode(thisNode.getNodeHandle());
00911             overlayCtrlInfo->setHopCount(msg->getHopCount());
00912             overlayCtrlInfo->setDestKey(msg->getDestKey());
00913             overlayCtrlInfo->setSrcNode(msg->getSrcNode());
00914 
00915             msg->setControlInfo(overlayCtrlInfo);
00916             callDeliver(msg);
00917         } else {
00918             // forward message to next hop
00919 
00920             // do we know the destination-node?
00921             if (neighbors->contains(msg->getDestKey())) {
00922                 // yes, destination-Node is our neighbor
00923                 GiaNode* target = neighbors->get
00924                                   (msg->getDestKey());
00925 
00926                 if (target->getReceivedTokens() == 0) {
00927                     // wait for free token
00928                     if (debugOutput)
00929                         EV << "(Gia) No free Node, wait for free token" << endl;
00930 
00931                     //bad code
00932                     std::string id;
00933                     if (!fromApplication)
00934                         id = "wait-for-token: " + msg->getID().toString();
00935                     else
00936                         id = "wait-for-token-fromapp: " +
00937                              msg->getID().toString();
00938                     cMessage* wait_timer = new cMessage(id.c_str());
00939                     wait_timer->encapsulate(msg);
00940                     scheduleAt(simulation.simTime() + tokenWaitTime,wait_timer);
00941                     return;
00942                 } else {
00943                     // decrease nextHop-tokencount
00944                     target->setReceivedTokens(target->getReceivedTokens()-1);
00945 
00946                     // forward msg to nextHop
00947                     msg->setHopCount(msg->getHopCount()-1);
00948                     msg->setSrcNode(thisNode.getNodeHandle());
00949                     msg->setSrcCapacity(thisNode.getCapacity());
00950                     msg->setSrcDegree(thisNode.getConnectionDegree());
00951                     if (debugOutput)
00952                         EV << "(Gia) Forwarding message " << msg
00953                         << " to neighbor " << *target << endl;
00954                     if (!fromApplication)
00955                         tokenFactory->grantToken();
00956 
00957                     stat_routeMessagesBytesSent += msg->byteLength();
00958                     stat_routeMessages += 1;
00959 
00960                     if(msg->getHopCount() > 0)
00961                         RECORD_STATS(numForwarded++; bytesForwarded +=
00962                                          msg->byteLength());
00963 
00964                     sendMessageToUDP(target->getNodeHandle(), msg);
00965                 }
00966             } else {
00967                 // no => pick node with at least one token and highest capacity
00968                 if (!msgBookkeepingList->contains(msg))
00969                     msgBookkeepingList->addMessage(msg);
00970                 GiaNode* nextHop = msgBookkeepingList->getNextHop(msg);
00971 
00972                 // do we have a neighbor who send us a token?
00973                 if (nextHop == NULL) {
00974                     // wait for free token
00975                     if (debugOutput)
00976                         EV << "(Gia) No free Node, wait for free token" << endl;
00977                     std::string id;
00978                     if (!fromApplication)
00979                         id = "wait-for-token: " + msg->getID().toString();
00980                     else
00981                         id = "wait-for-token-fromapp: " +
00982                              msg->getID().toString();
00983                     cMessage* wait_timer = new cMessage(id.c_str());
00984                     wait_timer->encapsulate(msg);
00985                     scheduleAt(simulation.simTime() + tokenWaitTime,wait_timer);
00986                     return;
00987                 } else {
00988                     // decrease nextHop-tokencount
00989                     nextHop->setReceivedTokens(nextHop->getReceivedTokens()-1);
00990 
00991                     // forward msg to nextHop
00992                     msg->setHopCount(msg->getHopCount()-1);
00993                     msg->setSrcNode(thisNode.getNodeHandle());
00994                     msg->setSrcCapacity(thisNode.getCapacity());
00995                     msg->setSrcDegree(thisNode.getConnectionDegree());
00996                     if (debugOutput)
00997                         EV << "(Gia) Forwarding message " << msg
00998                         << " to " << *nextHop << endl;
00999                     if (!fromApplication)
01000                         tokenFactory->grantToken();
01001 
01002                     stat_routeMessagesBytesSent += msg->byteLength();
01003                     stat_routeMessages += 1;
01004 
01005                     if(msg->getHopCount() > 0)
01006                         RECORD_STATS(numForwarded++; bytesForwarded +=
01007                                          msg->byteLength());
01008 
01009                     sendMessageToUDP(nextHop->getNodeHandle(), msg);
01010                 }
01011             }
01012         }
01013     }
01014 }

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
00845 {
00846     if (responseMsg->getHopCount() != 0) {
00847         uint reversePathArraySize = responseMsg->getReversePathArraySize();
00848 
00849         // reached node which started search?
00850         if (reversePathArraySize == 0) {
00851             deliverSearchResult(responseMsg);
00852         }
00853         // forward message to next node in reverse path list
00854         else {
00855             GiaNode* targetNode = neighbors->get
00856                                   (responseMsg->getReversePath(
00857                                        reversePathArraySize-1));
00858 
00859             if(!(targetNode->isUnspecified())) {
00860                 responseMsg->setDestKey(targetNode->getNodeHandle().key);
00861                 responseMsg->setReversePathArraySize(reversePathArraySize-1);
00862                 for (uint i=0; i<reversePathArraySize-1; i++)
00863                     responseMsg->setReversePath(i,
00864                                                 responseMsg->getReversePath(i));
00865                 responseMsg->setLength(responseMsg->length() - KEY_L);
00866 
00867                 stat_routeMessagesBytesSent += responseMsg->byteLength();
00868                 stat_routeMessages += 1;
00869 
00870                 if(responseMsg->getHopCount() > 0)
00871                     RECORD_STATS(numForwarded++; bytesForwarded +=
00872                                      responseMsg->byteLength());
00873 
00874                 sendMessageToUDP(targetNode->getNodeHandle(), responseMsg);
00875             } else {
00876                 EV << "(Gia) wrong reverse path in " << *responseMsg
00877                 << " ... deleted!" << endl;
00878                 RECORD_STATS(numDropped++;
00879                              bytesDropped += responseMsg->byteLength());
00880                 delete responseMsg;
00881             }
00882         }
00883     }
00884     // max hopcount reached. delete message
00885     else
00886         delete responseMsg;
00887 }

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.

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

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

Sends messages to UDP and collects statistical data.

Reimplemented from BaseOverlay.

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

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

Processes messages from underlay.

Parameters:
msg Message from UDP

Implements BaseOverlay.

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

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<KeyListModule*>
00061                     (parentModule()->submodule("keyListModule"));
00062     neighbors = check_and_cast<Neighbors*>
00063                 (parentModule()->submodule("neighbors"));
00064     tokenFactory = check_and_cast<TokenFactory*>
00065                    (parentModule()->submodule("tokenFactory"));
00066 
00067     msgBookkeepingList = new MessageBookkeeping(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::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
01149 {
01150     OverlayKey searchKey = msg->getSearchKey();
01151 
01152     if (keyList.contains(searchKey)) {
01153         // this node contains search key
01154         sendSearchResponseMessage(thisNode, msg);
01155     }
01156 
01157     // check if neighbors contain search key
01158     for (uint i = 0; i < neighbors->getSize(); i++) {
01159         KeyList* keyList = neighbors->getNeighborKeyList(i);
01160         if (keyList->contains(searchKey))
01161             sendSearchResponseMessage(*(neighbors->get
01162                                         (i)), msg);
01163     }
01164 
01165     // forward search-message to next hop
01166     if (msg->getMaxResponses() > 0) {
01167         // actualize reverse path
01168         uint reversePathSize = msg->getReversePathArraySize();
01169 
01170         if (optimizeReversePath)
01171             for (uint i=0; i<reversePathSize; i++) {
01172                 if (msg->getReversePath(i) == thisNode.getNodeHandle().key) {
01173                     // Our node already in ReversePath.
01174                     // Delete successor nodes from ReversePath
01175                     msg->setLength(msg->length() - (reversePathSize - i)*KEY_L);
01176                     reversePathSize = i; // set new array size
01177                     break;
01178                 }
01179             }
01180 
01181         msg->setReversePathArraySize(reversePathSize+1);
01182         msg->setReversePath(reversePathSize, thisNode.getNodeHandle().key);
01183         msg->setLength(msg->length() + KEY_L);
01184 
01185         forwardMessage(msg, fromApplication);
01186     } else {
01187         tokenFactory->grantToken();
01188         delete msg;
01189     }
01190 }

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

00072     {}

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

Removes newNode from our NeighborList.

Parameters:
newNode 
00633 {
00634     stat_removedNeighbors++;
00635     int position = neighbors->getPosition(node);
00636     if (position != -1) {
00637         if (debugOutput)
00638             EV << "(Gia) " << thisNode << " removes " << node
00639             << " from neighborlist." << endl;
00640         neighbors->remove
00641         (position);
00642 
00643         thisNode.setConnectionDegree(neighbors->getSize());
00644         if (neighbors->getSize() == 0)
00645             changeState(OVERLAY_NOT_READY);
00646     }
00647     deleteOverlayNeighborArrow(node.getNodeHandle());
00648 
00649     cancelEvent(update_timer);
00650     scheduleAt(simulation.simTime() + updateDelay, update_timer);
00651 }

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.

01017 {
01018     if (state == OVERLAY_READY) {
01019         GiaRouteMessage* routeMsg = new GiaRouteMessage("ROUTE");
01020         routeMsg->setSignaling(false);
01021         routeMsg->setCommand(ROUTE);
01022         routeMsg->setHopCount(maxHopCount);
01023         routeMsg->setDestKey(key);
01024         routeMsg->setSrcNode(thisNode.getNodeHandle());
01025         routeMsg->setSrcCapacity(thisNode.getCapacity());
01026         routeMsg->setSrcDegree(thisNode.getConnectionDegree());
01027         routeMsg->setOriginatorKey(thisNode.getNodeHandle().key);
01028         routeMsg->setOriginatorIP(thisNode.getNodeHandle().ip);
01029         routeMsg->setOriginatorPort(thisNode.getNodeHandle().port);
01030         routeMsg->setID(OverlayKey::random());
01031         routeMsg->encapsulate(msg);
01032         routeMsg->setLength(GIAROUTE_L(routeMsg));
01033 
01034         forwardMessage(routeMsg, true);
01035     } else {
01036         RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
01037         delete msg;
01038     }
01039 }

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

Sends KeyList to node dst.

Parameters:
dst,: Destination
00794 {
00795     // send KEYLIST:IND message
00796     KeyListMessage* msg = new KeyListMessage("KEYLIST");
00797     msg->setCommand(KEYLIST);
00798     msg->setSrcNode(thisNode.getNodeHandle());
00799     msg->setSrcCapacity(thisNode.getCapacity());
00800     msg->setSrcDegree(thisNode.getConnectionDegree());
00801 
00802     msg->setKeysArraySize(keyList.getSize());
00803     for (uint i=0; i<keyList.getSize(); i++)
00804         msg->setKeys(i, keyList.get(i));
00805 
00806     msg->setLength(KEYLIST_L(msg));
00807 
00808     stat_keyListMessagesBytesSent += msg->byteLength();
00809     stat_keyListMessages += 1;
00810 
00811     sendMessageToUDP(dst.getNodeHandle(), msg);
00812 }

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

Sends DISCONNECT_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00762 {
00763     // send DISCONNECT:IND message
00764     GiaMessage* msg = new GiaMessage("DISCONNECT");
00765     msg->setCommand(DISCONNECT);
00766     msg->setSrcNode(src.getNodeHandle());
00767     msg->setSrcCapacity(src.getCapacity());
00768     msg->setSrcDegree(src.getConnectionDegree());
00769     msg->setLength(GIA_L(msg));
00770 
00771     stat_disconnectMessagesBytesSent += msg->byteLength();
00772     stat_disconnectMessages += 1;
00773 
00774     sendMessageToUDP(dst, msg);
00775 }

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

Sends JOIN_ACK_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00719 {
00720     // send JOIN:ACK message
00721     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_ACK");
00722     msg->setCommand(JOIN_ACK);
00723     msg->setSrcNode(src.getNodeHandle());
00724     msg->setSrcCapacity(src.getCapacity());
00725     msg->setSrcDegree(src.getConnectionDegree());
00726 
00727     msg->setNeighborsArraySize(neighbors->getSize());
00728     //TODO: add parameter maxSendNeighbors
00729     for(uint i = 0; i < neighbors->getSize(); i++)
00730         msg->setNeighbors(i, *(neighbors->get
00731                                (i)));
00732 
00733     msg->setLength(GIANEIGHBOR_L(msg));
00734 
00735     stat_joinCount += 1;
00736     stat_joinBytesSent += msg->byteLength();
00737     stat_joinACK += 1;
00738     stat_joinACKBytesSent += msg->byteLength();
00739 
00740     sendMessageToUDP(dst, msg);
00741 }

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

Sends JOIN_DNY_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00744 {
00745     // send JOIN:DNY message
00746     GiaMessage* msg = new GiaMessage("JOIN_DENY");
00747     msg->setCommand(JOIN_DENY);
00748     msg->setSrcNode(src.getNodeHandle());
00749     msg->setSrcCapacity(src.getCapacity());
00750     msg->setSrcDegree(src.getConnectionDegree());
00751     msg->setLength(GIA_L(msg));
00752 
00753     stat_joinCount += 1;
00754     stat_joinBytesSent += msg->byteLength();
00755     stat_joinDNY += 1;
00756     stat_joinDNYBytesSent += msg->byteLength();
00757 
00758     sendMessageToUDP(dst, msg);
00759 }

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

Sends JOIN_REQ_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00676 {
00677     // send JOIN:REQ message
00678     GiaMessage* msg = new GiaMessage("JOIN_REQ");
00679     msg->setCommand(JOIN_REQUEST);
00680     msg->setSrcNode(src.getNodeHandle());
00681     msg->setSrcCapacity(src.getCapacity());
00682     msg->setSrcDegree(src.getConnectionDegree());
00683     msg->setLength(GIA_L(msg));
00684 
00685     stat_joinCount += 1;
00686     stat_joinBytesSent += msg->byteLength();
00687     stat_joinREQ += 1;
00688     stat_joinREQBytesSent += msg->byteLength();
00689 
00690     sendMessageToUDP(dst, msg);
00691 }

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

Sends JOIN_RSP_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00694 {
00695     // send JOIN:RSP message
00696     GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_RSP");
00697     msg->setCommand(JOIN_RESPONSE);
00698     msg->setSrcNode(src.getNodeHandle());
00699     msg->setSrcCapacity(src.getCapacity());
00700     msg->setSrcDegree(src.getConnectionDegree());
00701 
00702     msg->setNeighborsArraySize(neighbors->getSize());
00703     //TODO: add parameter maxSendNeighbors
00704     for(uint i = 0; i < neighbors->getSize(); i++)
00705         msg->setNeighbors(i, *(neighbors->get
00706                                (i)));
00707 
00708     msg->setLength(GIANEIGHBOR_L(msg));
00709 
00710     stat_joinCount += 1;
00711     stat_joinBytesSent += msg->byteLength();
00712     stat_joinRSP += 1;
00713     stat_joinRSPBytesSent += msg->byteLength();
00714 
00715     sendMessageToUDP(dst, msg);
00716 }

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

Sends UPDATE_Message from node src to node dst.

Parameters:
src,: Source
dst,: Destination
00778 {
00779     // send UPDATE:IND message
00780     GiaMessage* msg = new GiaMessage("UPDATE");
00781     msg->setCommand(UPDATE);
00782     msg->setSrcNode(src.getNodeHandle());
00783     msg->setSrcCapacity(src.getCapacity());
00784     msg->setSrcDegree(src.getConnectionDegree());
00785     msg->setLength(GIA_L(msg));
00786 
00787     stat_updateMessagesBytesSent += msg->byteLength();
00788     stat_updateMessages += 1;
00789 
00790     sendMessageToUDP(dst, msg);
00791 }

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

void Gia::sendToken ( const GiaNode dst  ) 

00815 {
00816     //GiaNode node = tokenQueue.top();
00817     TokenMessage* tokenMsg = new TokenMessage("TOKEN");
00818     tokenMsg->setCommand(TOKEN);
00819     tokenMsg->setHopCount(maxHopCount);
00820     tokenMsg->setSrcNode(thisNode.getNodeHandle());
00821     tokenMsg->setSrcCapacity(thisNode.getCapacity());
00822     tokenMsg->setSrcDegree(thisNode.getConnectionDegree());
00823     tokenMsg->setSrcTokenNr(dst.getReceivedTokens());
00824     tokenMsg->setDstTokenNr(dst.getSentTokens()+1);
00825     tokenMsg->setLength(TOKEN_L(tokenMsg));
00826 
00827     stat_tokenMessagesBytesSent += tokenMsg->byteLength();
00828     stat_tokenMessages += 1;
00829 
00830     sendMessageToUDP(dst.getNodeHandle(), tokenMsg);
00831 }

void Gia::setBootstrapedIcon (  )  [virtual]

Marks nodes if they are ready.

00209 {
00210     if (ev.isGUI()) {
00211         if (state == OVERLAY_READY) {
00212             parentModule()->parentModule()->displayString().
00213             setTagArg("i2", 1, "");
00214             displayString().setTagArg("i", 1, "");
00215         } else {
00216             parentModule()->parentModule()->displayString().
00217             setTagArg("i2", 1, "red");
00218             displayString().setTagArg("i", 1, "red");
00219         }
00220     }
00221 }

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

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

Parameters:
msg Received message
00834 {
00835     if(neighbors->contains(msg->getSrcNode().key)) {
00836         GiaNode* target = neighbors->get
00837                           (msg->getSrcNode().key);
00838         target->setConnectionDegree(msg->getSrcDegree());
00839         target->setCapacity(msg->getSrcCapacity());
00840         neighbors->updateTimestamp(*target);
00841     }
00842 }


Member Data Documentation

NodeHandle Gia::bootstrapNode [protected]

next possible neighbor candidate

KeyList Gia::keyList [protected]

key list of this node

double Gia::keyListDelay [protected]

delay to send the keylist to our neighbors

KeyListModule* Gia::keyListModule [protected]

pointer to KeyListModule

NeighborCandidateList Gia::knownNodes [protected]

list of known nodes in the overlay

double Gia::levelOfSatisfaction [protected]

current level of statisfaction

uint Gia::maxHopCount [protected]

maximum time to live for sent messages

double Gia::maxLevelOfSatisfaction [protected]

maximum level of satisfaction

uint Gia::maxNeighbors [protected]

maximum number of neighbors

uint Gia::maxTopAdaptionInterval [protected]

maximum topology adaption interval

uint Gia::messageTimeout [protected]

timeout for messages

uint Gia::minNeighbors [protected]

minimum number of neighbors

MessageBookkeeping* Gia::msgBookkeepingList [protected]

pointer to a message bookkeeping list

Neighbors* Gia::neighbors [protected]

pointer to neighbor list

uint Gia::neighborTimeout [protected]

timeout for neighbors

NeighborCandidateList Gia::neighCand [protected]

list of all neighbor candidates

bool Gia::optimizeReversePath [protected]

use optimized reverse path?

bool Gia::outputNodeDetails [protected]

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

cMessage* Gia::satisfaction_timer [protected]

timer for satisfaction self-message

cMessage* Gia::sendKeyList_timer [protected]

timer for send keylist

uint Gia::stat_addedNeighbors [protected]

number of added neighbors during life cycle of this node

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_joinACK [protected]

number of sent join acknowledge messages

uint Gia::stat_joinACKBytesSent [protected]

number of sent bytes of join acknowledge messages

uint Gia::stat_joinBytesSent [protected]

number of sent bytes of join messages

uint Gia::stat_joinCount [protected]

number of sent join 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_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_keyListMessages [protected]

number of sent keylist messages

uint Gia::stat_keyListMessagesBytesSent [protected]

number of sent bytes of keylist messages

double Gia::stat_maxLevelOfSatisfaction [protected]

maximum level of satisfaction

uint Gia::stat_maxNeighbors [protected]

maximum number of neighbors

uint Gia::stat_numSatisfactionMessages [protected]

number of satisfaction self-messages

uint Gia::stat_removedNeighbors [protected]

number of removed neighbors during life cycle of this node

uint Gia::stat_routeMessages [protected]

number of sent route messages

uint Gia::stat_routeMessagesBytesSent [protected]

number of sent bytes of route messages

double Gia::stat_sumLevelOfSatisfaction [protected]

sum of level of satisfaction

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_updateMessages [protected]

number of sent update messages

uint Gia::stat_updateMessagesBytesSent [protected]

number of sent bytes of update messages

int Gia::state [protected]

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

GiaNode Gia::thisNode [protected]

this node

Reimplemented from BaseOverlay.

cMessage* Gia::timedoutMessages_timer [protected]

timer for message timeout

cMessage* Gia::timedoutNeighbors_timer [protected]

timer for neighbors timeout

TokenFactory* Gia::tokenFactory [protected]

pointer to TokenFactory

uint Gia::tokenWaitTime [protected]

delay to send a new token

uint Gia::topAdaptionAggressiveness [protected]

the topology adaption aggressiveness

cMessage* Gia::update_timer [protected]

timer for update self-message

double Gia::updateDelay [protected]

time between to update messages (in ms)


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:37:06 2007 for ITM OverSim by  doxygen 1.4.7