#include <Gia.h>
Inheritance diagram for Gia:
Implementation of the Gia overlay as described in "Making Gnutella-like P2P Systems Scalable" by Y. Chawathe et al. published at SIGCOMM'03
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 | |
MessageBookkeeping * | msgBookkeepingList |
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 | |
KeyListModule * | keyListModule |
pointer to KeyListModule | |
Neighbors * | neighbors |
pointer to neighbor list | |
TokenFactory * | tokenFactory |
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 |
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 }
bool Gia::acceptNode | ( | const GiaNode & | newNode | ) | [protected] |
Decides if Node newNode will be accepted as new neighor.
newNode | Node to accept or deny |
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.
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.
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.
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.
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.
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.
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.
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.
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
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
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::removeNeighbor | ( | const GiaNode & | newNode | ) | [protected] |
Removes newNode from our NeighborList.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 }
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] |
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)