00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <assert.h>
00025
00026 #include <UDPControlInfo_m.h>
00027 #include <IPAddressResolver.h>
00028 #include <GlobalStatistics.h>
00029 #include <CommonMessages_m.h>
00030 #include <ExtAPIMessages_m.h>
00031 #include <InitStages.h>
00032 #include <BootstrapList.h>
00033
00034 #include "Gia.h"
00035
00036
00037 Define_Module(Gia);
00038
00039 void Gia::initializeOverlay(int stage)
00040 {
00041
00042 if(stage != MIN_STAGE_OVERLAY)
00043 return;
00044
00045
00046 maxNeighbors = par("maxNeighbors");
00047 minNeighbors = par("minNeighbors");
00048 maxTopAdaptionInterval = par("maxTopAdaptionInterval");
00049 topAdaptionAggressiveness = par("topAdaptionAggressiveness");
00050 maxLevelOfSatisfaction = par("maxLevelOfSatisfaction");
00051 updateDelay = par("updateDelay");
00052 maxHopCount = par("maxHopCount");
00053 messageTimeout = par("messageTimeout");
00054 neighborTimeout = par("neighborTimeout");
00055 sendTokenTimeout = par("sendTokenTimeout");
00056 tokenWaitTime = par("tokenWaitTime");
00057 keyListDelay = par("keyListDelay");
00058 outputNodeDetails = par("outputNodeDetails");
00059 optimizeReversePath = par("optimizeReversePath");
00060
00061
00062 keyListModule = check_and_cast<GiaKeyListModule*>
00063 (getParentModule()->getSubmodule("keyListModule"));
00064 neighbors = check_and_cast<GiaNeighbors*>
00065 (getParentModule()->getSubmodule("neighbors"));
00066 tokenFactory = check_and_cast<GiaTokenFactory*>
00067 (getParentModule()->getSubmodule("tokenFactory"));
00068
00069 msgBookkeepingList = new GiaMessageBookkeeping(neighbors, messageTimeout);
00070
00071
00072 neighCand.clear();
00073 knownNodes.clear();
00074
00075 WATCH(thisGiaNode);
00076 WATCH(bootstrapNode);
00077 WATCH(levelOfSatisfaction);
00078
00079
00080 satisfaction_timer = new cMessage("satisfaction_timer");
00081 update_timer = new cMessage("update_timer");
00082 timedoutMessages_timer = new cMessage("timedoutMessages_timer");
00083 timedoutNeighbors_timer = new cMessage("timedoutNeighbors_timer");
00084 sendKeyList_timer = new cMessage("sendKeyList_timer");
00085 sendToken_timer = new cMessage("sendToken_timer");
00086
00087
00088 stat_joinCount = 0;
00089 stat_joinBytesSent = 0;
00090 stat_joinREQ = 0;
00091 stat_joinREQBytesSent = 0;
00092 stat_joinRSP = 0;
00093 stat_joinRSPBytesSent = 0;
00094 stat_joinACK = 0;
00095 stat_joinACKBytesSent = 0;
00096 stat_joinDNY = 0;
00097 stat_joinDNYBytesSent = 0;
00098 stat_disconnectMessages = 0;
00099 stat_disconnectMessagesBytesSent = 0;
00100 stat_updateMessages = 0;
00101 stat_updateMessagesBytesSent = 0;
00102 stat_tokenMessages = 0;
00103 stat_tokenMessagesBytesSent = 0;
00104 stat_keyListMessages = 0;
00105 stat_keyListMessagesBytesSent = 0;
00106 stat_routeMessages = 0;
00107 stat_routeMessagesBytesSent = 0;
00108 stat_maxNeighbors = 0;
00109 stat_addedNeighbors = 0;
00110 stat_removedNeighbors = 0;
00111 stat_numSatisfactionMessages = 0;
00112 stat_sumLevelOfSatisfaction = 0.0;
00113 stat_maxLevelOfSatisfaction = 0.0;
00114 }
00115
00116 void Gia::joinOverlay()
00117 {
00118 changeState(INIT);
00119
00120 if (bootstrapNode.isUnspecified())
00121 changeState(READY);
00122 }
00123
00124 void Gia::changeState(int toState)
00125 {
00126 switch (toState) {
00127 case INIT: {
00128 state = INIT;
00129
00130 setOverlayReady(false);
00131 showOverlayNeighborArrow(thisGiaNode);
00132
00133
00134
00135 thisGiaNode = thisNode;
00136
00137 callUpdate(thisNode, true);
00138
00139
00140 double capacity = 0;
00141
00142 cModule* nodeModule = getParentModule()->getParentModule();
00143
00144 if(!nodeModule->hasGate("pppg$i"))
00145 capacity += uniform(1,800000);
00146 else {
00147
00148 int gateSize = nodeModule->gateSize("pppg$i");
00149 for (int i=0; i<gateSize; i++) {
00150 cGate* currentGate = nodeModule->gate("pppg$i",i);
00151 if (currentGate->isConnected())
00152 capacity += check_and_cast<cDatarateChannel *>
00153 (currentGate->getPreviousGate()->getChannel())->getDatarate()
00154 - uniform(0,800000);
00155 }
00156 }
00157
00158 thisGiaNode.setCapacity(capacity);
00159
00160
00161
00162
00163 connectionDegree = 0;
00164 receivedTokens = 0;
00165 sentTokens = 0;
00166
00167 if (outputNodeDetails)
00168 EV << "(Gia) Node details: " << thisGiaNode << endl;
00169
00170
00171 bootstrapNode = bootstrapList->getBootstrapNode();
00172 if(!(bootstrapNode.isUnspecified()))
00173 knownNodes.add(bootstrapNode);
00174
00175
00176
00177
00178
00179
00180
00181 tokenFactory->setNeighbors(neighbors);
00182 tokenFactory->setMaxHopCount(maxHopCount);
00183
00184 if (debugOutput)
00185 EV << "(Gia) Node " << thisGiaNode.getKey()
00186 << " (" << thisGiaNode.getAddress() << ":"
00187 << thisGiaNode.getPort() << ") with capacity: "
00188 << thisGiaNode.getCapacity() << " entered INIT state." << endl;
00189
00190 getParentModule()->getParentModule()->bubble("Enter INIT state.");
00191
00192
00193 cancelEvent(satisfaction_timer);
00194 scheduleAt(simTime(), satisfaction_timer);
00195
00196
00197 cancelEvent(timedoutMessages_timer);
00198 scheduleAt(simTime() + messageTimeout,
00199 timedoutMessages_timer);
00200
00201 cancelEvent(timedoutNeighbors_timer);
00202 scheduleAt(simTime() + neighborTimeout,
00203 timedoutNeighbors_timer);
00204
00205 cancelEvent(sendToken_timer);
00206 scheduleAt(simTime() + sendTokenTimeout,
00207 sendToken_timer);
00208
00209 break;
00210 }
00211 case READY:
00212 state = READY;
00213 setOverlayReady(true);
00214 break;
00215 }
00216 updateTooltip();
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 void Gia::updateTooltip()
00235 {
00236 if (ev.isGUI()) {
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 std::stringstream ttString;
00248
00249
00250 ttString << thisNode << "\n# Neighbors: "
00251 << neighbors->getSize();
00252
00253 getParentModule()->getParentModule()->getDisplayString().
00254 setTagArg("tt", 0, ttString.str().c_str());
00255 getParentModule()->getDisplayString().
00256 setTagArg("tt", 0, ttString.str().c_str());
00257 getDisplayString().setTagArg("tt", 0, ttString.str().c_str());
00258 }
00259 }
00260
00261 void Gia::handleTimerEvent(cMessage* msg)
00262 {
00263 if (msg == sendToken_timer) {
00264 tokenFactory->grantToken();
00265 } else if (msg->isName("satisfaction_timer")) {
00266
00267
00268 levelOfSatisfaction = calculateLevelOfSatisfaction();
00269 stat_numSatisfactionMessages++;
00270 stat_sumLevelOfSatisfaction += levelOfSatisfaction;
00271 if (levelOfSatisfaction > stat_maxLevelOfSatisfaction)
00272 stat_maxLevelOfSatisfaction = levelOfSatisfaction;
00273
00274
00275 scheduleAt(simTime() + (maxTopAdaptionInterval *
00276 pow(topAdaptionAggressiveness,
00277 -(1 - levelOfSatisfaction))),
00278 satisfaction_timer);
00279
00280
00281
00282 if(levelOfSatisfaction < maxLevelOfSatisfaction) {
00283 if(knownNodes.getSize() == 0) {
00284 if(neighbors->getSize() == 0 && neighCand.getSize() == 0)
00285 knownNodes.add(globalNodeList->getBootstrapNode());
00286 else
00287 return;
00288 }
00289
00290 NodeHandle possibleNeighbor = knownNodes.getRandomCandidate();
00291
00292 if(!(possibleNeighbor.isUnspecified()) &&
00293 thisGiaNode != possibleNeighbor &&
00294 !neighbors->contains(possibleNeighbor) &&
00295 !neighCand.contains(possibleNeighbor)) {
00296
00297 neighCand.add(possibleNeighbor);
00298 sendMessage_JOIN_REQ(possibleNeighbor);
00299 }
00300 }
00301 } else if (msg->isName("update_timer")) {
00302
00303 for (uint32_t i=0; i<neighbors->getSize(); i++) {
00304 sendMessage_UPDATE(neighbors->get(i));
00305 }
00306 } else if (msg->isName("timedoutMessages_timer")) {
00307
00308 msgBookkeepingList->removeTimedoutMessages();
00309 scheduleAt(simTime() + messageTimeout,
00310 timedoutMessages_timer);
00311 } else if (msg->isName("timedoutNeighbors_timer")) {
00312
00313 neighbors->removeTimedoutNodes();
00314 if (neighbors->getSize() == 0) {
00315 changeState(INIT);
00316 }
00317 cancelEvent(timedoutNeighbors_timer);
00318 scheduleAt(simTime() + neighborTimeout,
00319 timedoutNeighbors_timer);
00320 } else if (msg->isName("sendKeyList_timer")) {
00321 if (keyList.getSize() > 0) {
00322
00323 for (uint32_t i=0; i<neighbors->getSize(); i++)
00324 sendKeyListToNeighbor(neighbors->get(i));
00325 }
00326 } else {
00327
00328
00329 const std::string id = msg->getName();
00330 if (id.substr(0, 16) == std::string("wait-for-token: ")) {
00331 cPacket* packet = check_and_cast<cPacket*>(msg);
00332 cMessage* decapsulatedMessage = packet->decapsulate();
00333 if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00334 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00335 (decapsulatedMessage);
00336 forwardMessage(message, false);
00337 }
00338 } else if (id.substr(0, 24) == std::string("wait-for-token-fromapp: ")) {
00339 cPacket* packet = check_and_cast<cPacket*>(msg);
00340 cMessage* decapsulatedMessage = packet->decapsulate();
00341 if (dynamic_cast<GiaIDMessage*>(decapsulatedMessage) != NULL) {
00342 GiaIDMessage* message = check_and_cast<GiaIDMessage*>
00343 (decapsulatedMessage);
00344 forwardMessage(message, true);
00345 }
00346 }
00347 delete msg;
00348 }
00349 }
00350
00351 void Gia::handleUDPMessage(BaseOverlayMessage* msg)
00352 {
00353 if(debugOutput)
00354 EV << "(Gia) " << thisGiaNode << " received udp message" << endl;
00355
00356 cPolymorphic* ctrlInfo = msg->removeControlInfo();
00357 if(ctrlInfo != NULL)
00358 delete ctrlInfo;
00359
00360
00361 if (dynamic_cast<TokenMessage*>(msg) != NULL) {
00362 TokenMessage* giaMsg = check_and_cast<TokenMessage*>(msg);
00363
00364
00365 if ((giaMsg->getCommand() == TOKEN)) {
00366 if(debugOutput)
00367 EV << "(Gia) Received Tokenmessage from "
00368 << giaMsg->getSrcNode() << endl;
00369
00370
00371 neighbors->increaseReceivedTokens(giaMsg->getSrcNode());
00372 updateNeighborList(giaMsg);
00373 }
00374 delete msg;
00375 }
00376
00377
00378 else if (dynamic_cast<GiaRouteMessage*>(msg) != NULL) {
00379 GiaRouteMessage* giaMsg = check_and_cast<GiaRouteMessage*>(msg);
00380 GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00381 giaMsg->getSrcDegree());
00382
00383 if((giaMsg->getCommand() == ROUTE)) {
00384 if(debugOutput)
00385 EV << "(Gia) Received ROUTE::IND from " << oppositeNode << endl;
00386
00387 if(state == READY) {
00388
00389 updateNeighborList(giaMsg);
00390 forwardMessage(giaMsg, false);
00391 }
00392 }
00393 }
00394
00395
00396 else if (dynamic_cast<KeyListMessage*>(msg) != NULL) {
00397 KeyListMessage* giaMsg = check_and_cast<KeyListMessage*>(msg);
00398 GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00399 giaMsg->getSrcDegree());
00400
00401 if (giaMsg->getCommand() == KEYLIST) {
00402 if (debugOutput)
00403 EV << "(Gia) " << thisGiaNode
00404 << " received KEYLIST:IND message" << endl;
00405
00406 uint32_t keyListSize = giaMsg->getKeysArraySize();
00407 GiaKeyList neighborKeyList;
00408 for (uint32_t k = 0; k < keyListSize; k++)
00409 neighborKeyList.addKeyItem(giaMsg->getKeys(k));
00410 neighbors->setNeighborKeyList(giaMsg->getSrcNode(), neighborKeyList);
00411 }
00412 delete giaMsg;
00413 }
00414
00415
00416 else if (dynamic_cast<SearchMessage*>(msg) != NULL) {
00417 SearchMessage* giaMsg = check_and_cast<SearchMessage*>(msg);
00418 GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00419 giaMsg->getSrcDegree());
00420
00421
00422 updateNeighborList(giaMsg);
00423 processSearchMessage(giaMsg, false);
00424
00425
00426
00427
00428
00429 }
00430
00431
00432 else if (dynamic_cast<SearchResponseMessage*>(msg) != NULL) {
00433 SearchResponseMessage* responseMsg =
00434 check_and_cast<SearchResponseMessage*>(msg);
00435 forwardSearchResponseMessage(responseMsg);
00436 }
00437
00438
00439 else if (dynamic_cast<GiaMessage*>(msg) != NULL) {
00440 GiaMessage* giaMsg = check_and_cast<GiaMessage*>(msg);
00441
00442
00443 GiaNode oppositeNode(giaMsg->getSrcNode(), giaMsg->getSrcCapacity(),
00444 giaMsg->getSrcDegree());
00445
00446 if (debugOutput)
00447 EV << "(Gia) " << thisGiaNode << " received GIA- message from "
00448 << oppositeNode << endl;
00449 updateNeighborList(giaMsg);
00450
00451
00452 if (giaMsg->getCommand() == JOIN_REQUEST) {
00453 if (debugOutput)
00454 EV << "(Gia) " << thisGiaNode
00455 << " received JOIN:REQ message" << endl;
00456 if (acceptNode(oppositeNode, giaMsg->getSrcDegree())) {
00457 neighCand.add(oppositeNode);
00458 sendMessage_JOIN_RSP(oppositeNode);
00459 } else {
00460 if (debugOutput)
00461 EV << "(Gia) " << thisGiaNode << " denies node "
00462 << oppositeNode << endl;
00463 sendMessage_JOIN_DNY(oppositeNode);
00464 }
00465 }
00466
00467
00468 else if (giaMsg->getCommand() == JOIN_RESPONSE) {
00469 if(debugOutput)
00470 EV << "(Gia) " << thisGiaNode << " received JOIN:RSP message"
00471 << endl;
00472 if(neighCand.contains(oppositeNode)) {
00473 neighCand.remove(oppositeNode);
00474 if(acceptNode(oppositeNode, giaMsg->getSrcDegree())) {
00475 addNeighbor(oppositeNode, giaMsg->getSrcDegree());
00476
00477 GiaNeighborMessage* msg =
00478 check_and_cast<GiaNeighborMessage*>(giaMsg);
00479 for(uint32_t i = 0; i < msg->getNeighborsArraySize(); i++) {
00480 GiaNode temp = msg->getNeighbors(i);
00481 if(temp != thisGiaNode && temp != oppositeNode)
00482 knownNodes.add(temp);
00483 }
00484
00485 sendMessage_JOIN_ACK(oppositeNode);
00486 } else {
00487 if (debugOutput)
00488 EV << "(Gia) " << thisGiaNode << " denies node "
00489 << oppositeNode << endl;
00490 sendMessage_JOIN_DNY(oppositeNode);
00491 }
00492 }
00493 }
00494
00495
00496 else if (giaMsg->getCommand() == JOIN_ACK) {
00497 if (debugOutput)
00498 EV << "(Gia) " << thisGiaNode << " received JOIN:ACK message"
00499 << endl;
00500 if (neighCand.contains(oppositeNode) &&
00501 neighbors->getSize() < maxNeighbors) {
00502 neighCand.remove(oppositeNode);
00503 addNeighbor(oppositeNode, giaMsg->getSrcDegree());
00504
00505 GiaNeighborMessage* msg =
00506 check_and_cast<GiaNeighborMessage*>(giaMsg);
00507
00508 for(uint32_t i = 0; i < msg->getNeighborsArraySize(); i++) {
00509 GiaNode temp = msg->getNeighbors(i);
00510 if(temp != thisGiaNode && temp != oppositeNode)
00511 knownNodes.add(msg->getNeighbors(i));
00512 }
00513 } else {
00514 sendMessage_DISCONNECT(oppositeNode);
00515 }
00516
00517 }
00518
00519
00520 else if (giaMsg->getCommand() == JOIN_DENY) {
00521 if (debugOutput)
00522 EV << "(Gia) " << thisGiaNode << " received JOIN:DNY message"
00523 << endl;
00524
00525 if (neighCand.contains(oppositeNode))
00526 neighCand.remove(oppositeNode);
00527 knownNodes.remove(oppositeNode);
00528
00529 }
00530
00531
00532
00533 else if (giaMsg->getCommand() == DISCONNECT) {
00534 if (debugOutput)
00535 EV << "(Gia) " << thisGiaNode << " received DISCONNECT:IND message" << endl;
00536 removeNeighbor(giaMsg->getSrcNode());
00537 }
00538
00539
00540 else if (giaMsg->getCommand() == UPDATE) {
00541 if (debugOutput)
00542 EV << "(Gia) " << thisGiaNode << " received UPDATE:IND message"
00543 << endl;
00544
00545 neighbors->setConnectionDegree(giaMsg->getSrcNode(),
00546 giaMsg->getSrcDegree());
00547
00548
00549 } else {
00550
00551 if (debugOutput) {
00552 EV << "(Gia) NODE: "<< thisGiaNode << endl
00553 << " Command: " << giaMsg->getCommand() << endl
00554 << " HopCount: " << giaMsg->getHopCount() << endl
00555 << " SrcKey: " << giaMsg->getSrcNode().getKey() << endl
00556 << " SrcIP: " << giaMsg->getSrcNode().getKey() << endl
00557 << " SrcPort: " << giaMsg->getSrcNode().getPort() << endl
00558 << " SrcCapacity: " << giaMsg->getSrcCapacity() << endl
00559 << " SrcDegree: " << giaMsg->getSrcDegree() << endl;
00560
00561 RECORD_STATS(numDropped++;bytesDropped += giaMsg->getByteLength());
00562 }
00563 }
00564 delete giaMsg;
00565 } else
00566 delete msg;
00567 }
00568
00569 bool Gia::acceptNode(const GiaNode& nNode, unsigned int degree)
00570 {
00571 if (neighbors->contains(nNode))
00572 return false;
00573
00574 if (neighbors->getSize() < maxNeighbors) {
00575
00576 return true;
00577 }
00578
00579 NodeHandle dropCandidate = neighbors->getDropCandidate(nNode.getCapacity(), degree);
00580 if(!dropCandidate.isUnspecified()) {
00581 if (debugOutput)
00582 EV << "(Gia) " << thisGiaNode << " drops "
00583 << dropCandidate << endl;
00584 neighbors->remove(dropCandidate);
00585 sendMessage_DISCONNECT(dropCandidate);
00586 return true;
00587 }
00588 return false;
00589 }
00590
00591
00592 void Gia::addNeighbor(GiaNode& node, unsigned int degree)
00593 {
00594 assert(neighbors->getSize() < maxNeighbors);
00595
00596 stat_addedNeighbors++;
00597 EV << "(Gia) " << thisGiaNode << " accepted new neighbor " << node << endl;
00598 getParentModule()->getParentModule()->bubble("New neighbor");
00599 connectionDegree = neighbors->getSize();
00600 changeState(READY);
00601 if (stat_maxNeighbors < neighbors->getSize()) {
00602 stat_maxNeighbors = neighbors->getSize();
00603 }
00604
00605 cancelEvent(update_timer);
00606 scheduleAt(simTime() + updateDelay, update_timer);
00607
00608
00609
00610
00611
00612 if (keyList.getSize() > 0)
00613 sendKeyListToNeighbor(node);
00614 neighbors->add(node, degree);
00615
00616 showOverlayNeighborArrow(node, false,
00617 "m=m,50,0,50,0;ls=red,1");
00618 updateTooltip();
00619 }
00620
00621 void Gia::removeNeighbor(const GiaNode& node)
00622 {
00623 stat_removedNeighbors++;
00624
00625 if (debugOutput)
00626 EV << "(Gia) " << thisGiaNode << " removes " << node
00627 << " from neighborlist." << endl;
00628 neighbors->remove(node);
00629
00630 connectionDegree = neighbors->getSize();
00631
00632 if (neighbors->getSize() == 0) {
00633 changeState(INIT);
00634 }
00635
00636 deleteOverlayNeighborArrow(node);
00637 updateTooltip();
00638
00639 cancelEvent(update_timer);
00640 scheduleAt(simTime() + updateDelay, update_timer);
00641 }
00642
00643 double Gia::calculateLevelOfSatisfaction()
00644 {
00645 uint32_t neighborsCount = neighbors->getSize();
00646 if(neighborsCount < minNeighbors)
00647 return 0.0;
00648
00649 double total = 0.0;
00650 double levelOfSatisfaction = 0.0;
00651
00652 for (uint32_t i=0; i < neighborsCount; i++)
00653 total += neighbors->get(i).getCapacity() / neighborsCount;
00654
00655 assert(thisGiaNode.getCapacity() != 0);
00656 levelOfSatisfaction = total / thisGiaNode.getCapacity();
00657
00658 if ((levelOfSatisfaction > 1.0) || (neighborsCount >= maxNeighbors))
00659 return 1.0;
00660 return levelOfSatisfaction;
00661 }
00662
00663
00664 void Gia::sendMessage_JOIN_REQ(const NodeHandle& dst)
00665 {
00666
00667 GiaMessage* msg = new GiaMessage("JOIN_REQ");
00668 msg->setCommand(JOIN_REQUEST);
00669 msg->setSrcNode(thisGiaNode);
00670 msg->setSrcCapacity(thisGiaNode.getCapacity());
00671 msg->setSrcDegree(connectionDegree);
00672 msg->setBitLength(GIA_L(msg));
00673
00674 stat_joinCount += 1;
00675 stat_joinBytesSent += msg->getByteLength();
00676 stat_joinREQ += 1;
00677 stat_joinREQBytesSent += msg->getByteLength();
00678
00679 sendMessageToUDP(dst, msg);
00680 }
00681
00682 void Gia::sendMessage_JOIN_RSP(const NodeHandle& dst)
00683 {
00684
00685 GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_RSP");
00686 msg->setCommand(JOIN_RESPONSE);
00687 msg->setSrcNode(thisGiaNode);
00688 msg->setSrcCapacity(thisGiaNode.getCapacity());
00689 msg->setSrcDegree(connectionDegree);
00690
00691 msg->setNeighborsArraySize(neighbors->getSize());
00692
00693 for(uint32_t i = 0; i < neighbors->getSize(); i++)
00694 msg->setNeighbors(i, neighbors->get(i));
00695
00696 msg->setBitLength(GIANEIGHBOR_L(msg));
00697
00698 stat_joinCount += 1;
00699 stat_joinBytesSent += msg->getByteLength();
00700 stat_joinRSP += 1;
00701 stat_joinRSPBytesSent += msg->getByteLength();
00702
00703 sendMessageToUDP(dst, msg);
00704 }
00705
00706 void Gia::sendMessage_JOIN_ACK(const NodeHandle& dst)
00707 {
00708
00709 GiaNeighborMessage* msg = new GiaNeighborMessage("JOIN_ACK");
00710 msg->setCommand(JOIN_ACK);
00711 msg->setSrcNode(thisGiaNode);
00712 msg->setSrcCapacity(thisGiaNode.getCapacity());
00713 msg->setSrcDegree(connectionDegree);
00714
00715 msg->setNeighborsArraySize(neighbors->getSize());
00716
00717 for(uint32_t i = 0; i < neighbors->getSize(); i++)
00718 msg->setNeighbors(i, neighbors->get(i));
00719
00720 msg->setBitLength(GIANEIGHBOR_L(msg));
00721
00722 stat_joinCount += 1;
00723 stat_joinBytesSent += msg->getByteLength();
00724 stat_joinACK += 1;
00725 stat_joinACKBytesSent += msg->getByteLength();
00726
00727 sendMessageToUDP(dst, msg);
00728 }
00729
00730 void Gia::sendMessage_JOIN_DNY(const NodeHandle& dst)
00731 {
00732
00733 GiaMessage* msg = new GiaMessage("JOIN_DENY");
00734 msg->setCommand(JOIN_DENY);
00735 msg->setSrcNode(thisGiaNode);
00736 msg->setSrcCapacity(thisGiaNode.getCapacity());
00737 msg->setSrcDegree(connectionDegree);
00738 msg->setBitLength(GIA_L(msg));
00739
00740 stat_joinCount += 1;
00741 stat_joinBytesSent += msg->getByteLength();
00742 stat_joinDNY += 1;
00743 stat_joinDNYBytesSent += msg->getByteLength();
00744
00745 sendMessageToUDP(dst, msg);
00746 }
00747
00748 void Gia::sendMessage_DISCONNECT(const NodeHandle& dst)
00749 {
00750
00751 GiaMessage* msg = new GiaMessage("DISCONNECT");
00752 msg->setCommand(DISCONNECT);
00753 msg->setSrcNode(thisGiaNode);
00754 msg->setSrcCapacity(thisGiaNode.getCapacity());
00755 msg->setSrcDegree(connectionDegree);
00756 msg->setBitLength(GIA_L(msg));
00757
00758 stat_disconnectMessagesBytesSent += msg->getByteLength();
00759 stat_disconnectMessages += 1;
00760
00761 sendMessageToUDP(dst, msg);
00762 }
00763
00764 void Gia::sendMessage_UPDATE(const NodeHandle& dst)
00765 {
00766
00767 GiaMessage* msg = new GiaMessage("UPDATE");
00768 msg->setCommand(UPDATE);
00769 msg->setSrcNode(thisGiaNode);
00770 msg->setSrcCapacity(thisGiaNode.getCapacity());
00771 msg->setSrcDegree(connectionDegree);
00772 msg->setBitLength(GIA_L(msg));
00773
00774 stat_updateMessagesBytesSent += msg->getByteLength();
00775 stat_updateMessages += 1;
00776
00777 sendMessageToUDP(dst, msg);
00778 }
00779
00780 void Gia::sendKeyListToNeighbor(const NodeHandle& dst)
00781 {
00782
00783 KeyListMessage* msg = new KeyListMessage("KEYLIST");
00784 msg->setCommand(KEYLIST);
00785 msg->setSrcNode(thisGiaNode);
00786 msg->setSrcCapacity(thisGiaNode.getCapacity());
00787 msg->setSrcDegree(connectionDegree);
00788
00789 msg->setKeysArraySize(keyList.getSize());
00790 for (uint32_t i=0; i<keyList.getSize(); i++)
00791 msg->setKeys(i, keyList.get(i));
00792
00793 msg->setBitLength(KEYLIST_L(msg));
00794
00795 stat_keyListMessagesBytesSent += msg->getByteLength();
00796 stat_keyListMessages += 1;
00797
00798 sendMessageToUDP(dst, msg);
00799 }
00800
00801 void Gia::sendToken(const GiaNode& dst)
00802 {
00803 TokenMessage* tokenMsg = new TokenMessage("TOKEN");
00804 tokenMsg->setCommand(TOKEN);
00805 tokenMsg->setHopCount(maxHopCount);
00806 tokenMsg->setSrcNode(thisGiaNode);
00807 tokenMsg->setSrcCapacity(thisGiaNode.getCapacity());
00808 tokenMsg->setSrcDegree(connectionDegree);
00809 tokenMsg->setSrcTokenNr(0);
00810 tokenMsg->setDstTokenNr(1);
00811 tokenMsg->setBitLength(TOKEN_L(tokenMsg));
00812
00813 stat_tokenMessagesBytesSent += tokenMsg->getByteLength();
00814 stat_tokenMessages += 1;
00815
00816 sendMessageToUDP(dst, tokenMsg);
00817 }
00818
00819 void Gia::updateNeighborList(GiaMessage* msg)
00820 {
00821 if(neighbors->contains(msg->getSrcNode().getKey())) {
00822 neighbors->setConnectionDegree(msg->getSrcNode(),msg->getSrcDegree());
00823
00824 neighbors->updateTimestamp(msg->getSrcNode());
00825 }
00826 }
00827
00828 void Gia::forwardSearchResponseMessage(SearchResponseMessage* responseMsg)
00829 {
00830 if (responseMsg->getHopCount() != 0) {
00831 uint32_t reversePathArraySize = responseMsg->getReversePathArraySize();
00832
00833
00834 if (reversePathArraySize == 0) {
00835 deliverSearchResult(responseMsg);
00836 }
00837
00838 else {
00839 NodeHandle targetNode = neighbors->get
00840 (responseMsg->getReversePath(
00841 reversePathArraySize-1));
00842
00843 if(!(targetNode.isUnspecified())) {
00844 responseMsg->setDestKey(targetNode.getKey());
00845 responseMsg->setReversePathArraySize(reversePathArraySize-1);
00846 for (uint32_t i=0; i<reversePathArraySize-1; i++)
00847 responseMsg->setReversePath(i, responseMsg->getReversePath(i));
00848 responseMsg->setBitLength(responseMsg->getBitLength() - KEY_L);
00849
00850 stat_routeMessagesBytesSent += responseMsg->getByteLength();
00851 stat_routeMessages += 1;
00852
00853 if(responseMsg->getHopCount() > 0)
00854 RECORD_STATS(numAppDataForwarded++; bytesAppDataForwarded +=
00855 responseMsg->getByteLength());
00856
00857 sendMessageToUDP(targetNode, responseMsg);
00858 } else {
00859 EV << "(Gia) wrong reverse path in " << *responseMsg
00860 << " ... deleted!" << endl;
00861 RECORD_STATS(numDropped++;
00862 bytesDropped += responseMsg->getByteLength());
00863 delete responseMsg;
00864 }
00865 }
00866 }
00867
00868 else
00869 delete responseMsg;
00870 }
00871
00872 void Gia::forwardMessage(GiaIDMessage* msg , bool fromApplication)
00873 {
00874 if (msg->getHopCount() == 0) {
00875
00876 if (!fromApplication)
00877 tokenFactory->grantToken();
00878 RECORD_STATS(numDropped++; bytesDropped += msg->getByteLength());
00879 delete msg;
00880 } else {
00881
00882 if (msg->getDestKey() == thisGiaNode.getKey()) {
00883 if(!fromApplication)
00884 tokenFactory->grantToken();
00885
00886 if(debugOutput)
00887 EV << "(Gia) Deliver messsage " << msg
00888 << " to application at " << thisGiaNode << endl;
00889
00890 OverlayCtrlInfo* overlayCtrlInfo =
00891 new OverlayCtrlInfo();
00892
00893 overlayCtrlInfo->setHopCount(msg->getHopCount());
00894 overlayCtrlInfo->setSrcNode(msg->getSrcNode());
00895 overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
00896 overlayCtrlInfo->setDestComp(TIER1_COMP);
00897 overlayCtrlInfo->setSrcComp(TIER1_COMP);
00898
00899 msg->setControlInfo(overlayCtrlInfo);
00900 callDeliver(msg, msg->getDestKey());
00901 } else {
00902
00903
00904
00905 if (neighbors->contains(msg->getDestKey())) {
00906
00907 NodeHandle targetNode = neighbors->get(msg->getDestKey());
00908 GiaNeighborInfo* targetInfo= neighbors->get(targetNode);
00909
00910 if (targetInfo->receivedTokens == 0) {
00911
00912 if (debugOutput)
00913 EV << "(Gia) No free Node, wait for free token" << endl;
00914
00915
00916 std::string id;
00917 if (!fromApplication)
00918 id = "wait-for-token: " + msg->getID().toString();
00919 else
00920 id = "wait-for-token-fromapp: " +
00921 msg->getID().toString();
00922 cPacket* wait_timer = new cPacket(id.c_str());
00923 wait_timer->encapsulate(msg);
00924 scheduleAt(simTime() + tokenWaitTime,wait_timer);
00925 return;
00926 } else {
00927
00928 neighbors->decreaseReceivedTokens(targetNode);
00929
00930
00931
00932 msg->setHopCount(msg->getHopCount()-1);
00933 msg->setSrcNode(thisGiaNode);
00934 msg->setSrcCapacity(thisGiaNode.getCapacity());
00935 msg->setSrcDegree(connectionDegree);
00936 if (debugOutput)
00937 EV << "(Gia) Forwarding message " << msg
00938 << " to neighbor " << targetNode << endl;
00939 if (!fromApplication)
00940 tokenFactory->grantToken();
00941
00942 stat_routeMessagesBytesSent += msg->getByteLength();
00943 stat_routeMessages += 1;
00944
00945 if(msg->getHopCount() > 0)
00946 RECORD_STATS(numAppDataForwarded++; bytesAppDataForwarded +=
00947 msg->getByteLength());
00948
00949 sendMessageToUDP(targetNode, msg);
00950 }
00951 } else {
00952
00953 if (!msgBookkeepingList->contains(msg))
00954 msgBookkeepingList->addMessage(msg);
00955 NodeHandle nextHop = msgBookkeepingList->getNextHop(msg);
00956
00957 if(nextHop.isUnspecified()) {
00958
00959 if (debugOutput)
00960 EV << "(Gia) No free Node, wait for free token" << endl;
00961 std::string id;
00962 if (!fromApplication)
00963 id = "wait-for-token: " + msg->getID().toString();
00964 else
00965 id = "wait-for-token-fromapp: " +
00966 msg->getID().toString();
00967 cPacket* wait_timer = new cPacket(id.c_str());
00968 wait_timer->encapsulate(msg);
00969 scheduleAt(simTime() + tokenWaitTime,wait_timer);
00970 return;
00971 } else {
00972 GiaNeighborInfo* nextHopInfo = neighbors->get(nextHop);
00973 if(nextHopInfo == NULL) {
00974 delete msg;
00975 return;
00976 }
00977
00978 neighbors->decreaseReceivedTokens(nextHop);
00979
00980
00981
00982 msg->setHopCount(msg->getHopCount()-1);
00983 msg->setSrcNode(thisGiaNode);
00984 msg->setSrcCapacity(thisGiaNode.getCapacity());
00985 msg->setSrcDegree(connectionDegree);
00986 if (debugOutput)
00987 EV << "(Gia) Forwarding message " << msg
00988 << " to " << nextHop << endl;
00989 if (!fromApplication)
00990 tokenFactory->grantToken();
00991
00992 stat_routeMessagesBytesSent += msg->getByteLength();
00993 stat_routeMessages += 1;
00994
00995 if(msg->getHopCount() > 0)
00996 RECORD_STATS(numAppDataForwarded++; bytesAppDataForwarded +=
00997 msg->getByteLength());
00998
00999 sendMessageToUDP(nextHop, msg);
01000 }
01001 }
01002 }
01003 }
01004 }
01005
01006 void Gia::getRoute(const OverlayKey& key, CompType destComp,
01007 CompType srcComp, cPacket* msg,
01008 const std::vector<TransportAddress>& sourceRoute,
01009 RoutingType routingType)
01010 {
01011 if ((destComp != TIER1_COMP) || (srcComp != TIER1_COMP)) {
01012 throw cRuntimeError("Gia::getRoute(): Works currently "
01013 "only with srcComp=destComp=TIER1_COMP!");
01014 }
01015
01016 if (state == READY) {
01017 GiaRouteMessage* routeMsg = new GiaRouteMessage("ROUTE");
01018 routeMsg->setStatType(APP_DATA_STAT);
01019 routeMsg->setCommand(ROUTE);
01020 routeMsg->setHopCount(maxHopCount);
01021 routeMsg->setDestKey(key);
01022 routeMsg->setSrcNode(thisGiaNode);
01023 routeMsg->setSrcCapacity(thisGiaNode.getCapacity());
01024 routeMsg->setSrcDegree(connectionDegree);
01025 routeMsg->setOriginatorKey(thisGiaNode.getKey());
01026 routeMsg->setOriginatorIP(thisGiaNode.getAddress());
01027 routeMsg->setOriginatorPort(thisGiaNode.getPort());
01028 routeMsg->setID(OverlayKey::random());
01029 routeMsg->setBitLength(GIAROUTE_L(routeMsg));
01030 routeMsg->encapsulate(msg);
01031
01032
01033 forwardMessage(routeMsg, true);
01034 } else {
01035 RECORD_STATS(numDropped++; bytesDropped += msg->getByteLength());
01036 delete msg;
01037 }
01038 }
01039
01040 void Gia::handleAppMessage(cMessage* msg)
01041 {
01042
01043 if (dynamic_cast<GIAput*>(msg) != NULL) {
01044 GIAput* putMsg = check_and_cast<GIAput*>(msg);
01045 uint32_t keyListSize = putMsg->getKeysArraySize();
01046 for (uint32_t k=0; k<keyListSize; k++)
01047 keyList.addKeyItem(putMsg->getKeys(k));
01048
01049
01050 keyListModule->setKeyListVector(keyList.getVector());
01051
01052 scheduleAt(simTime() + keyListDelay, sendKeyList_timer);
01053
01054 delete putMsg;
01055 } else if (dynamic_cast<GIAsearch*>(msg) != NULL) {
01056 if (state == READY) {
01057 GIAsearch* getMsg = check_and_cast<GIAsearch*>(msg);
01058 SearchMessage* searchMsg = new SearchMessage("SEARCH");
01059 searchMsg->setCommand(SEARCH);
01060 searchMsg->setStatType(APP_DATA_STAT);
01061 searchMsg->setHopCount(maxHopCount);
01062 searchMsg->setDestKey(getMsg->getSearchKey());
01063 searchMsg->setSrcNode(thisGiaNode);
01064 searchMsg->setSrcCapacity(thisGiaNode.getCapacity());
01065 searchMsg->setSrcDegree(connectionDegree);
01066 searchMsg->setSearchKey(getMsg->getSearchKey());
01067 searchMsg->setMaxResponses(getMsg->getMaxResponses());
01068 searchMsg->setReversePathArraySize(0);
01069 searchMsg->setID(OverlayKey::random());
01070 searchMsg->setBitLength(SEARCH_L(searchMsg));
01071
01072 processSearchMessage(searchMsg, true);
01073
01074 delete getMsg;
01075 } else
01076 delete msg;
01077 } else {
01078 delete msg;
01079 EV << "(Gia) unkown message from app deleted!" << endl;
01080 }
01081 }
01082
01083
01084 void Gia::sendSearchResponseMessage(const GiaNode& srcNode, SearchMessage* msg)
01085 {
01086
01087 uint32_t foundNodeArraySize = msg->getFoundNodeArraySize();
01088 bool containsNode = false;
01089 for (uint32_t i=0; i<foundNodeArraySize; i++)
01090 if (srcNode.getKey() == msg->getFoundNode(i))
01091 containsNode = true;
01092
01093 if (!containsNode && msg->getMaxResponses() > 0) {
01094
01095 msg->setFoundNodeArraySize(foundNodeArraySize+1);
01096 msg->setFoundNode(foundNodeArraySize, srcNode.getKey());
01097
01098
01099 msg->setMaxResponses(msg->getMaxResponses()-1);
01100
01101
01102 uint32_t reversePathArraySize = msg->getReversePathArraySize();
01103
01104 if (reversePathArraySize == 0) {
01105
01106
01107 SearchResponseMessage* responseMsg =
01108 new SearchResponseMessage("ANSWER");
01109 responseMsg->setCommand(ANSWER);
01110 responseMsg->setStatType(APP_DATA_STAT);
01111 responseMsg->setHopCount(maxHopCount);
01112 responseMsg->setSrcNode(thisGiaNode);
01113 responseMsg->setSrcCapacity(thisGiaNode.getCapacity());
01114 responseMsg->setSrcDegree(connectionDegree);
01115 responseMsg->setSearchKey(msg->getSearchKey());
01116 responseMsg->setFoundNode(srcNode);
01117 responseMsg->setID(OverlayKey::random());
01118 responseMsg->setSearchHopCount(0);
01119
01120 responseMsg->setBitLength(SEARCHRESPONSE_L(responseMsg));
01121
01122 deliverSearchResult(responseMsg);
01123 } else {
01124 uint32_t reversePathArraySize(msg->getReversePathArraySize());
01125 SearchResponseMessage* responseMsg =
01126 new SearchResponseMessage("ANSWER");
01127 responseMsg->setCommand(ANSWER);
01128 responseMsg->setHopCount(maxHopCount);
01129 responseMsg->setSrcNode(srcNode);
01130 responseMsg->setSrcCapacity(srcNode.getCapacity());
01131 responseMsg->setSrcDegree(connectionDegree);
01132 responseMsg->setSearchKey(msg->getSearchKey());
01133 responseMsg->setFoundNode(srcNode);
01134 responseMsg->setReversePathArraySize(reversePathArraySize);
01135 for (uint32_t i=0; i<reversePathArraySize; i++)
01136 responseMsg->setReversePath(i, msg->getReversePath(i));
01137 responseMsg->setID(OverlayKey::random());
01138 responseMsg->setSearchHopCount(reversePathArraySize);
01139 responseMsg->setBitLength(SEARCHRESPONSE_L(responseMsg));
01140
01141 forwardSearchResponseMessage(responseMsg);
01142 }
01143 }
01144 }
01145
01146
01147 void Gia::processSearchMessage(SearchMessage* msg, bool fromApplication)
01148 {
01149 OverlayKey searchKey = msg->getSearchKey();
01150
01151 if (keyList.contains(searchKey)) {
01152
01153 sendSearchResponseMessage(thisGiaNode, msg);
01154 }
01155
01156
01157 for (uint32_t i = 0; i < neighbors->getSize(); i++) {
01158 GiaKeyList* keyList = neighbors->getNeighborKeyList(neighbors->get(i));
01159 if (keyList->contains(searchKey))
01160 sendSearchResponseMessage(neighbors->get(i), msg);
01161 }
01162
01163
01164 if (msg->getMaxResponses() > 0) {
01165
01166 uint32_t reversePathSize = msg->getReversePathArraySize();
01167
01168 if (optimizeReversePath)
01169 for (uint32_t i=0; i<reversePathSize; i++) {
01170 if (msg->getReversePath(i) == thisGiaNode.getKey()) {
01171
01172
01173 msg->setBitLength(msg->getBitLength() - (reversePathSize - i)*KEY_L);
01174 reversePathSize = i;
01175 break;
01176 }
01177 }
01178
01179 msg->setReversePathArraySize(reversePathSize+1);
01180 msg->setReversePath(reversePathSize, thisGiaNode.getKey());
01181 msg->setBitLength(msg->getBitLength() + KEY_L);
01182
01183 forwardMessage(msg, fromApplication);
01184 } else {
01185 tokenFactory->grantToken();
01186 delete msg;
01187 }
01188 }
01189
01190 void Gia::deliverSearchResult(SearchResponseMessage* msg)
01191 {
01192 OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo();
01193 overlayCtrlInfo->setHopCount(msg->getSearchHopCount());
01194 overlayCtrlInfo->setSrcNode(msg->getSrcNode());
01195 overlayCtrlInfo->setTransportType(ROUTE_TRANSPORT);
01196
01197 GIAanswer* deliverMsg = new GIAanswer("GIA-Answer");
01198 deliverMsg->setCommand(GIA_ANSWER);
01199 deliverMsg->setControlInfo(overlayCtrlInfo);
01200 deliverMsg->setSearchKey(msg->getSearchKey());
01201 deliverMsg->setNode(msg->getFoundNode());
01202 deliverMsg->setBitLength(GIAGETRSP_L(msg));
01203
01204 send(deliverMsg, "appOut");
01205 if (debugOutput)
01206 EV << "(Gia) Deliver search response " << msg
01207 << " to application at " << thisGiaNode << endl;
01208
01209 delete msg;
01210 }
01211
01212 void Gia::finishOverlay()
01213 {
01214
01215
01216 globalStatistics->addStdDev("GIA: JOIN-Messages Count", stat_joinCount);
01217 globalStatistics->addStdDev("GIA: JOIN Bytes sent", stat_joinBytesSent);
01218 globalStatistics->addStdDev("GIA: JOIN::REQ Messages", stat_joinREQ);
01219 globalStatistics->addStdDev("GIA: JOIN::REQ Bytes sent", stat_joinREQBytesSent);
01220 globalStatistics->addStdDev("GIA: JOIN::RSP Messages", stat_joinRSP);
01221 globalStatistics->addStdDev("GIA: JOIN::RSP Bytes sent", stat_joinRSPBytesSent);
01222 globalStatistics->addStdDev("GIA: JOIN::ACK Messages", stat_joinACK);
01223 globalStatistics->addStdDev("GIA: JOIN::ACK Bytes sent", stat_joinACKBytesSent);
01224 globalStatistics->addStdDev("GIA: JOIN::DNY Messages", stat_joinDNY);
01225 globalStatistics->addStdDev("GIA: JOIN::DNY Bytes sent", stat_joinDNYBytesSent);
01226 globalStatistics->addStdDev("GIA: DISCONNECT:IND Messages", stat_disconnectMessages);
01227 globalStatistics->addStdDev("GIA: DISCONNECT:IND Bytes sent",
01228 stat_disconnectMessagesBytesSent);
01229 globalStatistics->addStdDev("GIA: UPDATE:IND Messages", stat_updateMessages);
01230 globalStatistics->addStdDev("GIA: UPDATE:IND Bytes sent", stat_updateMessagesBytesSent);
01231 globalStatistics->addStdDev("GIA: TOKEN:IND Messages", stat_tokenMessages);
01232 globalStatistics->addStdDev("GIA: TOKEN:IND Bytes sent", stat_tokenMessagesBytesSent);
01233 globalStatistics->addStdDev("GIA: KEYLIST:IND Messages", stat_keyListMessages);
01234 globalStatistics->addStdDev("GIA: KEYLIST:IND Bytes sent", stat_keyListMessagesBytesSent);
01235 globalStatistics->addStdDev("GIA: ROUTE:IND Messages", stat_routeMessages);
01236 globalStatistics->addStdDev("GIA: ROUTE:IND Bytes sent", stat_routeMessagesBytesSent);
01237 globalStatistics->addStdDev("GIA: Neighbors max", stat_maxNeighbors);
01238 globalStatistics->addStdDev("GIA: Neighbors added", stat_addedNeighbors);
01239 globalStatistics->addStdDev("GIA: Neighbors removed", stat_removedNeighbors);
01240 globalStatistics->addStdDev("GIA: Level of satisfaction messages ",
01241 stat_numSatisfactionMessages);
01242 globalStatistics->addStdDev("GIA: Level of satisfaction max ",stat_maxLevelOfSatisfaction);
01243 globalStatistics->addStdDev("GIA: Level of satisfaction avg ",
01244 stat_sumLevelOfSatisfaction / stat_numSatisfactionMessages);
01245 bootstrapList->removeBootstrapNode(thisGiaNode);
01246 }
01247
01248 Gia::~Gia()
01249 {
01250 cancelAndDelete(satisfaction_timer);
01251 cancelAndDelete(update_timer);
01252 cancelAndDelete(timedoutMessages_timer);
01253 cancelAndDelete(timedoutNeighbors_timer);
01254 cancelAndDelete(sendKeyList_timer);
01255 cancelAndDelete(sendToken_timer);
01256 delete msgBookkeepingList;
01257 }
01258