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