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