00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "Broose.h"
00025 #include <RpcMacros.h>
00026 #include <GlobalStatistics.h>
00027 #include <IPAddressResolver.h>
00028 #include <BootstrapList.h>
00029 #include <LookupListener.h>
00030
00031 using namespace std;
00032
00033 Define_Module(Broose);
00034
00035 class BrooseLookupListener : public LookupListener
00036 {
00037 private:
00038 Broose* overlay;
00039 public:
00040 BrooseLookupListener(Broose* overlay)
00041 {
00042 this->overlay = overlay;
00043 }
00044
00045 virtual void lookupFinished(AbstractLookup *lookup)
00046 {
00047 delete this;
00048 }
00049 };
00050
00051 Broose::Broose()
00052 {
00053 join_timer = NULL;
00054 bucket_timer = NULL;
00055 rBucket = NULL;
00056 lBucket = NULL;
00057 bBucket = NULL;
00058 }
00059 Broose::~Broose()
00060 {
00061
00062 cancelAndDelete(join_timer);
00063 cancelAndDelete(bucket_timer);
00064 }
00065
00066 void Broose::initializeOverlay(int stage)
00067 {
00068
00069
00070 if (stage != MIN_STAGE_OVERLAY)
00071 return;
00072
00073
00074 kbr = true;
00075
00076
00077 bucketSize = par("bucketSize");
00078 rBucketSize = par("rBucketSize");
00079 joinDelay = par("joinDelay");
00080 shiftingBits = par("brooseShiftingBits");
00081 userDist = par("userDist");
00082 refreshTime = par("refreshTime");
00083 numberRetries = par("numberRetries");
00084 stab1 = par("stab1");
00085 stab2 = par("stab2");
00086
00087
00088 bucketCount = 0;
00089 bucketBytesSent = 0;
00090
00091
00092 chooseLookup = 0;
00093 receivedJoinResponse = 0;
00094 receivedBBucketLookup = 0;
00095 numberBBucketLookup = 0;
00096 receivedLBucketLookup = 0;
00097 numberLBucketLookup = 0;
00098 powShiftingBits = 1 << shiftingBits;
00099 keyLength = OverlayKey::getLength();
00100 numFailedPackets = 0;
00101 bucketRetries = 0;
00102
00103
00104 WATCH(receivedJoinResponse);
00105 WATCH(receivedBBucketLookup);
00106 WATCH(numberBBucketLookup);
00107 WATCH(receivedLBucketLookup);
00108 WATCH(numberLBucketLookup);
00109 WATCH(state);
00110
00111
00112 rBucket = new BrooseBucket*[powShiftingBits];
00113
00114 for (int i = 0; i < powShiftingBits; i++) {
00115 rBucket[i] = check_and_cast<BrooseBucket*>
00116 (getParentModule()->getSubmodule("rBucket",i));
00117 bucketVector.push_back(rBucket[i]);
00118 }
00119
00120 lBucket = check_and_cast<BrooseBucket*>
00121 (getParentModule()->getSubmodule("lBucket"));
00122 bucketVector.push_back(lBucket);
00123
00124 bBucket = check_and_cast<BrooseBucket*>
00125 (getParentModule()->getSubmodule("bBucket"));
00126 bucketVector.push_back(bBucket);
00127
00128
00129 join_timer = new cMessage("join_timer");
00130 bucket_timer = new cMessage("bucket_timer");
00131 }
00132
00133 void Broose::joinOverlay()
00134 {
00135 changeState(INIT);
00136
00137
00138
00139 if (bootstrapNode.isUnspecified()) {
00140 changeState(READY);
00141 }
00142 }
00143
00144
00145 void Broose::changeState(int toState)
00146 {
00147 switch (toState) {
00148 case INIT: {
00149 state = INIT;
00150
00151
00152 bootstrapNode = bootstrapList->getBootstrapNode();
00153
00154 cancelEvent(join_timer);
00155 scheduleAt(simTime(), join_timer);
00156
00157
00158 for (int i = 0; i < powShiftingBits; i++) {
00159 rBucket[i]->initializeBucket(shiftingBits, i, rBucketSize, this);
00160 }
00161
00162 lBucket->initializeBucket(-shiftingBits, 0, powShiftingBits*rBucketSize,
00163 this);
00164 bBucket->initializeBucket(0, 0, 7*bucketSize, this, true);
00165
00166
00167 receivedBBucketLookup = 0;
00168 receivedLBucketLookup = 0;
00169 receivedJoinResponse = 0;
00170
00171 getParentModule()->getParentModule()->bubble("Enter INIT state.");
00172 updateTooltip();
00173 break;
00174 }
00175
00176 case RSET: {
00177 state = RSET;
00178
00179 BrooseBucket* tmpBucket = new BrooseBucket();
00180 tmpBucket->initializeBucket(0, 0, powShiftingBits*rBucketSize, this);
00181
00182 for (int i = 0; i < powShiftingBits; i++) {
00183 int size = rBucket[i]->getSize();
00184
00185 for (int j = 0; j < size; j++) {
00186 tmpBucket->add(rBucket[i]->get(j));
00187 }
00188 }
00189
00190 BucketCall** bCall = new BucketCall*[tmpBucket->getSize()];
00191 for (uint32_t i = 0; i < tmpBucket->getSize(); i++) {
00192 bCall[i] = new BucketCall("LBucketCall");
00193 bCall[i]->setBucketType(LEFT);
00194 bCall[i]->setProState(PRSET);
00195 bCall[i]->setBitLength(BUCKETCALL_L(bcall[i]));
00196
00197 sendUdpRpcCall(tmpBucket->get(i), bCall[i], NULL,
00198 10);
00199 }
00200
00201
00202 numberBBucketLookup = ceil((double)tmpBucket->getSize() / 2);
00203
00204 delete tmpBucket;
00205
00206 getParentModule()->getParentModule()->bubble("Enter RSET state.");
00207 break;
00208 }
00209
00210 case BSET: {
00211 state = BSET;
00212
00213
00214 numberLBucketLookup = ceil((double)bBucket->getSize() / 2);
00215
00216
00217 int size2 = bBucket->getSize();
00218 BucketCall** bCall2 = new BucketCall*[size2];
00219 for (int i = 0; i < size2; i++) {
00220 bCall2[i] = new BucketCall("LBucketCall");
00221 bCall2[i]->setBucketType(LEFT);
00222 bCall2[i]->setProState(PBSET);
00223 bCall2[i]->setBitLength(BUCKETCALL_L(bcall2[i]));
00224
00225 sendUdpRpcCall(bBucket->get(i), bCall2[i], NULL,
00226 10);
00227 }
00228
00229 getParentModule()->getParentModule()->bubble("Enter BSET state.");
00230 break;
00231 }
00232
00233 case READY: {
00234 state = READY;
00235
00236
00237 for (size_t i = 0; i < bucketVector.size(); i++) {
00238 bucketVector[i]->add(thisNode);
00239 }
00240
00241
00242
00243 if (refreshTime != 0) {
00244 cancelEvent(bucket_timer);
00245 scheduleAt(simTime() + (refreshTime / 2.0), bucket_timer);
00246 }
00247
00248 getParentModule()->getParentModule()->bubble("Enter READY state.");
00249
00250 updateTooltip();
00251 break;
00252 }
00253
00254 }
00255 setOverlayReady(state == READY);
00256 }
00257
00258 void Broose::handleTimerEvent(cMessage* msg)
00259 {
00260 if (msg == join_timer)
00261 handleJoinTimerExpired(msg);
00262 else if (msg == bucket_timer)
00263 handleBucketTimerExpired(msg);
00264 else
00265 error("Broose::handleTimerEvent - no other timer currently in use!");
00266 }
00267
00268 void Broose::handleJoinTimerExpired(cMessage* msg)
00269 {
00270 if (state == READY)
00271 return;
00272
00273 if (!bootstrapNode.isUnspecified()) {
00274
00275 #if 0
00276 BucketCall* bCall = new BucketCall();
00277 bCall->setBucketType(BROTHER);
00278 bCall->setProState(FAILED);
00279 bCall->setBitLength(BUCKETCALL_L(call));
00280 sendRouteRpcCall(OVERLAY_COMP, bootstrapNode, thisNode.getKey(),
00281 bCall);
00282
00283 BucketCall* lCall = new BucketCall();
00284 lCall->setBucketType(BROTHER);
00285 lCall->setProState(FAILED);
00286 lCall->setBitLength(BUCKETCALL_L(call));
00287 sendRouteRpcCall(OVERLAY_COMP, bootstrapNode,
00288 thisNode.getKey() << shiftingBits, lCall);
00289 #endif
00290
00291 OverlayKey newKey = thisNode.getKey() >> shiftingBits;
00292 BucketCall* bCallArray[powShiftingBits];
00293 for (int i = 0; i < powShiftingBits; i++) {
00294 OverlayKey add(i);
00295 add = add << (keyLength - shiftingBits);
00296 add += newKey;
00297
00298 bCallArray[i] = new BucketCall("BBucketCall");
00299 bCallArray[i]->setBucketType(BROTHER);
00300 bCallArray[i]->setBucketIndex(i);
00301 bCallArray[i]->setProState(PINIT);
00302 bCallArray[i]->setBitLength(BUCKETCALL_L(bCallArray[i]));
00303
00304
00305
00306 sendRouteRpcCall(OVERLAY_COMP, bootstrapNode, add,
00307 bCallArray[i]);
00308 }
00309
00310
00311 } else {
00312
00313
00314 changeState(READY);
00315 }
00316 }
00317
00318 void Broose::handleBucketTimerExpired(cMessage* msg)
00319 {
00320 BrooseBucket* tmpBucket = new BrooseBucket();
00321 tmpBucket->initializeBucket(0, 0,
00322 (2*powShiftingBits*rBucketSize + 7*bucketSize),
00323 this);
00324
00325 for (size_t i = 0; i < bucketVector.size(); i++) {
00326 for(uint32_t j = 0; j < bucketVector[i]->getSize(); j++) {
00327 if ((simTime() - bucketVector[i]->getLastSeen(
00328 bucketVector[i]->get(j))) > refreshTime
00329 || bucketVector[i]->getRTT(bucketVector[i]->get(j)) == -1) {
00330
00331 tmpBucket->add(BrooseHandle(bucketVector[i]->get(j)));
00332 }
00333 }
00334 }
00335
00336 for (uint32_t i = 0; i < tmpBucket->getSize(); i++) {
00337 pingNode(tmpBucket->get(i));
00338 }
00339
00340 delete tmpBucket;
00341
00342 scheduleAt(simTime() + (refreshTime / 2.0), bucket_timer);
00343 }
00344
00345
00346 int Broose::getMaxNumSiblings()
00347 {
00348 return bucketSize;
00349 }
00350
00351 int Broose::getMaxNumRedundantNodes()
00352 {
00353 return bucketSize;
00354 }
00355
00356 int Broose::getRoutingDistance(const OverlayKey& key, const OverlayKey& node,
00357 int dist)
00358 {
00359 for (uint i = 0; i < (uint)abs(dist); i++) {
00360 if (node.sharedPrefixLength(key << i) >= (abs(dist) - i)) {
00361 return i;
00362 }
00363 if (key.sharedPrefixLength(node << i) >= (abs(dist) - i)) {
00364 return -i;
00365 }
00366 }
00367
00368 if (((chooseLookup++) % 2) == 0) {
00369 return -dist;
00370 } else {
00371 return dist;
00372 }
00373 }
00374
00375 #if 0
00376
00377
00378 NodeVector* Broose::findNode(const OverlayKey& key,
00379 int numRedundantNodes,
00380 int numSiblings,
00381 BaseOverlayMessage* msg)
00382 {
00383 BrooseFindNodeExtMessage *findNodeExt = NULL;
00384 bool err;
00385 bool isSibling = isSiblingFor(thisNode, key, numSiblings, &err);
00386 int resultSize;
00387
00388 if (numSiblings < 0) {
00389
00390 resultSize = numRedundantNodes;
00391 } else {
00392 resultSize = isSibling ? (numSiblings ? numSiblings : 1)
00393 : numRedundantNodes;
00394 }
00395 assert(numSiblings || numRedundantNodes);
00396 NodeVector* result = new NodeVector(resultSize);
00397
00398 if (isSibling) {
00399
00400
00401 KeyDistanceComparator<KeyXorMetric>* comp =
00402 new KeyDistanceComparator<KeyXorMetric>(key);
00403 result->setComparator(comp);
00404
00405 bBucket->fillVector(result);
00406 result->add(thisNode);
00407
00408 delete comp;
00409
00410
00411 std::cout << "key: " << key.toString(2).substr(0, 8)
00412 << " ThisNode: " << thisNode.getKey().toString(2).substr(0, 8);
00413 if (result->size() > 0) {
00414 std::cout << " next hop (final): " << (*result)[0].getKey().toString(2).substr(0, 8);
00415 } else {
00416 std::cout << " no next hop! (final)";
00417 }
00418 std::cout << std::endl << std::endl;
00419
00420
00421 return result;
00422 }
00423
00424
00425 int dist = max(rBucket[0]->longestPrefix(),
00426 rBucket[1]->longestPrefix()) + 1 + userDist;
00427
00428 if ((dist % shiftingBits) != 0)
00429 dist += (shiftingBits - (dist % shiftingBits));
00430
00431 if (dist > keyLength) {
00432 if ((keyLength % shiftingBits) == 0) {
00433 dist = keyLength;
00434 } else {
00435 dist = (keyLength - keyLength % shiftingBits);
00436 }
00437 }
00438
00439 if (msg != NULL) {
00440 if (!msg->hasObject("findNodeExt")) {
00441 findNodeExt = new BrooseFindNodeExtMessage("findNodeExt");
00442
00443 findNodeExt->setMaxDistance(dist);
00444
00445
00446 findNodeExt->setLastNode(thisNode);
00447 findNodeExt->setBitLength(BROOSEFINDNODEEXTMESSAGE_L);
00448
00449 msg->addObject( findNodeExt );
00450 }
00451
00452 findNodeExt = (BrooseFindNodeExtMessage*) msg->getObject("findNodeExt");
00453 }
00454
00455
00456 routingAdd(findNodeExt->getLastNode(), true);
00457
00458
00459
00460 findNodeExt->setLastNode(thisNode);
00461
00462
00463
00464 int step = getRoutingDistance(key, thisNode.getKey(),
00465 findNodeExt->getMaxDistance());
00466
00467 bool leftShifting;
00468 if (step < 0) {
00469 leftShifting = true;
00470 step *= -1;
00471 }
00472
00473 if ((step % shiftingBits) != 0)
00474 step += (shiftingBits - (step % shiftingBits));
00475
00476 if (step > keyLength) {
00477 if ((keyLength % shiftingBits) == 0) {
00478 step = keyLength;
00479 } else {
00480 step = (keyLength - keyLength % shiftingBits);
00481 }
00482 }
00483
00484 if (leftShifting) {
00485 step *= -1;
00486 }
00487
00488
00489 if (step == 0) {
00490
00491
00492 KeyDistanceComparator<KeyXorMetric>* comp =
00493 new KeyDistanceComparator<KeyXorMetric>(key);
00494 result->setComparator(comp);
00495
00496 bBucket->fillVector(result);
00497 result->add(thisNode);
00498
00499
00500 std::cout << "key: " << key.toString(2).substr(0, 8)
00501 << " dist: " << step << " (max: " << findNodeExt->getMaxDistance() << ")"
00502 << " rtkey: " << thisNode.getKey().toString(2).substr(0, 8)
00503 << " ThisNode: " << thisNode.getKey().toString(2).substr(0, 8);
00504 if (result->size() > 0) {
00505 std::cout << " next hop: " << (*result)[0].getKey().toString(2).substr(0, 8);
00506 } else {
00507 std::cout << " no next hop!";
00508 }
00509 std::cout << std::endl << std::endl;
00510
00511
00512 delete comp;
00513 return result;
00514 } else if (step < 0) {
00515 if (state == BSET) {
00516 return result;
00517 }
00518
00519 OverlayKey routingKey = key >> (-step - 1);
00520 for (int i = 0; i < (-step - 1); i++) {
00521 routingKey.setBit(OverlayKey::getLength() - i - 1,
00522 thisNode.getKey().getBit(
00523 OverlayKey::getLength() - i - 2));
00524 }
00525
00526 KeyDistanceComparator<KeyXorMetric>* comp =
00527 new KeyDistanceComparator<KeyXorMetric>(routingKey);
00528
00529 result->setComparator(comp);
00530 lBucket->fillVector(result);
00531 result->add(thisNode);
00532 delete comp;
00533
00534 std::cout << "key: " << key.toString(2).substr(0, 8)
00535 << " dist: " << step << " (max: " << findNodeExt->getMaxDistance() << ")"
00536 << " rtkey: " << routingKey.toString(2).substr(0, 8)
00537 << " ThisNode: " << thisNode.getKey().toString(2).substr(0, 8);
00538 if (result->size() > 0) {
00539 std::cout << " next hop: " << (*result)[0].getKey().toString(2).substr(0, 8);
00540 } else {
00541 std::cout << " no next hop!";
00542 }
00543 std::cout << std::endl << std::endl;
00544
00545
00546 } else {
00547
00548 KeyDistanceComparator<KeyXorMetric>* comp = NULL;
00549 comp = new KeyDistanceComparator<KeyXorMetric>(key << (step - shiftingBits));
00550
00551 result->setComparator(comp);
00552 rBucket[key.getBitRange(key.getLength() - step - 1,
00553 shiftingBits)]->fillVector(result);
00554 result->add(thisNode);
00555 delete comp;
00556
00557 std::cout << "key: " << key.toString(2).substr(0, 8)
00558 << " dist: " << step << " (max: " << findNodeExt->getMaxDistance() << ")"
00559 << " rtkey: " << (key >> step).toString(2).substr(0, 8)
00560 << " ThisNode: " << thisNode.getKey().toString(2).substr(0, 8);
00561 if (result->size() > 0) {
00562 std::cout << " next hop: " << (*result)[0].getKey().toString(2).substr(0, 8);
00563 } else {
00564 std::cout << " no next hop!";
00565 }
00566 std::cout << std::endl << std::endl;
00567
00568 }
00569
00570 return result;
00571 }
00572 #endif
00573
00574 NodeVector* Broose::findNode(const OverlayKey& key,
00575 int numRedundantNodes,
00576 int numSiblings,
00577 BaseOverlayMessage* msg)
00578 {
00579 if ((state == INIT) || (state == RSET) || (state == FAILED))
00580 return new NodeVector();
00581
00582 BrooseFindNodeExtMessage *findNodeExt = NULL;
00583 bool err;
00584 bool isSibling = isSiblingFor(thisNode, key, numSiblings, &err);
00585 int resultSize;
00586
00587 if (numSiblings < 0) {
00588
00589 resultSize = numRedundantNodes;
00590 } else {
00591 resultSize = isSibling ? (numSiblings ? numSiblings : 1)
00592 : numRedundantNodes;
00593 }
00594 assert(numSiblings || numRedundantNodes);
00595 NodeVector* result = new NodeVector(resultSize);
00596
00597 if (isSibling) {
00598
00599
00600 KeyDistanceComparator<KeyXorMetric>* comp =
00601 new KeyDistanceComparator<KeyXorMetric>(key);
00602 result->setComparator(comp);
00603
00604 bBucket->fillVector(result);
00605 result->add(thisNode);
00606
00607 delete comp;
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 return result;
00621 }
00622
00623 if (msg != NULL) {
00624 if (!msg->hasObject("findNodeExt")) {
00625 findNodeExt = new BrooseFindNodeExtMessage("findNodeExt");
00626
00627 OverlayKey routeKey = thisNode.getKey();
00628
00629 int dist = max(rBucket[0]->longestPrefix(),
00630 rBucket[1]->longestPrefix()) + 1 + userDist;
00631
00632 if ((dist % shiftingBits) != 0)
00633 dist += (shiftingBits - (dist % shiftingBits));
00634
00635 if (dist > keyLength) {
00636 if ((keyLength % shiftingBits) == 0) {
00637 dist = keyLength;
00638 } else {
00639 dist = (keyLength - keyLength % shiftingBits);
00640 }
00641 }
00642
00643 if ((chooseLookup++) % 2 == 0) {
00644
00645 findNodeExt->setRightShifting(false);
00646
00647 int prefix = 0;
00648 for (int i = 0; i < dist; i++) {
00649 prefix += thisNode.getKey().getBit(thisNode.getKey().getLength() - i - 1) << (dist - i - 1);
00650 }
00651
00652 OverlayKey pre(prefix);
00653 routeKey = key >> dist;
00654 routeKey += (pre << key.getLength() - dist);
00655
00656 dist = -dist;
00657 } else {
00658
00659 findNodeExt->setRightShifting(true);
00660 }
00661
00662
00663 findNodeExt->setLastNode(thisNode);
00664 findNodeExt->setRouteKey(routeKey);
00665 findNodeExt->setStep(dist);
00666 findNodeExt->setBitLength(BROOSEFINDNODEEXTMESSAGE_L);
00667
00668 msg->addObject( findNodeExt );
00669 }
00670
00671 findNodeExt = (BrooseFindNodeExtMessage*) msg->getObject("findNodeExt");
00672 }
00673
00674
00675 addNode(findNodeExt->getLastNode());
00676 setLastSeen(findNodeExt->getLastNode());
00677
00678
00679
00680 findNodeExt->setLastNode(thisNode);
00681
00682
00683 if (findNodeExt->getStep() == 0) {
00684
00685 KeyDistanceComparator<KeyXorMetric>* comp =
00686 new KeyDistanceComparator<KeyXorMetric>(key);
00687 result->setComparator(comp);
00688
00689 bBucket->fillVector(result);
00690 result->add(thisNode);
00691
00692 delete comp;
00693 return result;
00694 }
00695
00696 if (findNodeExt->getRightShifting() == false) {
00697
00698
00699
00700 if (state == BSET)
00701 return result;
00702
00703
00704 findNodeExt->setRouteKey((findNodeExt->getRouteKey()) << shiftingBits);
00705 findNodeExt->setStep(findNodeExt->getStep() + shiftingBits);
00706
00707 KeyDistanceComparator<KeyXorMetric>* comp = NULL;
00708 comp = new KeyDistanceComparator<KeyXorMetric>(
00709 findNodeExt->getRouteKey());
00710
00711 result->setComparator(comp);
00712 lBucket->fillVector(result);
00713 result->add(thisNode);
00714 delete comp;
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 } else {
00729
00730
00731
00732
00733 int prefix = 0;
00734 int dist = findNodeExt->getStep();
00735 OverlayKey routeKey = findNodeExt->getRouteKey() >> shiftingBits;
00736 for (int i = 0; i < shiftingBits; i++)
00737 prefix += ((int)key.getBit(key.getLength() - dist + i) << i);
00738 OverlayKey pre(prefix);
00739 routeKey += (pre << (routeKey.getLength()-shiftingBits));
00740
00741 findNodeExt->setRouteKey(routeKey);
00742 findNodeExt->setStep(dist - shiftingBits);
00743
00744 KeyDistanceComparator<KeyXorMetric>* comp = NULL;
00745 comp = new KeyDistanceComparator<KeyXorMetric>(routeKey);
00746
00747 result->setComparator(comp);
00748 rBucket[prefix]->fillVector(result);
00749 result->add(thisNode);
00750 delete comp;
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 }
00764
00765 if ((*result)[0] == thisNode) {
00766 delete result;
00767 return (findNode(key, numRedundantNodes, numSiblings, msg));
00768 } else
00769 return result;
00770 }
00771
00772 void Broose::finishOverlay()
00773 {
00774
00775 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00776 if (time < GlobalStatistics::MIN_MEASURED) return;
00777
00778 globalStatistics->addStdDev("Broose: Number of non-routable packets/s", numFailedPackets / time);
00779 globalStatistics->addStdDev("Broose: Sent BUCKET Messages/s", bucketCount / time);
00780 globalStatistics->addStdDev("Broose: Sent BUCKET Byte/s", bucketBytesSent / time);
00781 globalStatistics->addStdDev("Broose: Bucket retries at join", bucketRetries);
00782
00783 }
00784
00785 void Broose::recordOverlaySentStats(BaseOverlayMessage* msg)
00786 {
00787 BaseOverlayMessage* innerMsg = msg;
00788 while (innerMsg->getType() != APPDATA &&
00789 innerMsg->getEncapsulatedPacket() != NULL) {
00790 innerMsg =
00791 static_cast<BaseOverlayMessage*>(innerMsg->getEncapsulatedPacket());
00792 }
00793
00794 switch (innerMsg->getType()) {
00795 case RPC:
00796 if ((dynamic_cast<BucketCall*>(innerMsg) != NULL) ||
00797 (dynamic_cast<BucketResponse*>(innerMsg) != NULL)) {
00798 RECORD_STATS(bucketCount++; bucketBytesSent +=
00799 msg->getByteLength());
00800 }
00801 break;
00802 }
00803 }
00804
00805 void Broose::displayBucketState()
00806 {
00807 EV << "[Broose::displayBucketState() @ " << thisNode.getAddress()
00808 << " (" << thisNode.getKey().toString(16) << ")]" << endl;
00809
00810 for (int i = 0; i < powShiftingBits; i++) {
00811 EV << " Content of rBucket[" << i << "]: ";
00812 rBucket[i]->output();
00813 }
00814
00815 EV << " Content of lBucket: ";
00816 lBucket->output();
00817 EV << " Content of bBucket: ";
00818 bBucket->output();
00819 EV << endl;
00820 }
00821
00822
00823 bool Broose::isSiblingFor(const NodeHandle& node,
00824 const OverlayKey& key,
00825 int numSiblings,
00826 bool* err)
00827 {
00828
00829 if (key.isUnspecified())
00830 error("Broose::isSiblingFor(): key is unspecified!");
00831
00832 if (node != thisNode)
00833 error("Broose::isSiblingsFor(): "
00834 "node != thisNode is not implemented!");
00835
00836 if (numSiblings > getMaxNumSiblings()) {
00837 opp_error("Broose::isSiblingFor(): numSiblings too big!");
00838 }
00839
00840 if (numSiblings == -1) numSiblings = getMaxNumSiblings();
00841
00842 if (numSiblings == 0) {
00843 *err = false;
00844 return (node.getKey() == key);
00845 }
00846
00847 if (state != READY) {
00848 *err = true;
00849 return false;
00850 }
00851
00852
00853 return bBucket->keyInRange(key);
00854 }
00855
00856 void Broose::updateTooltip()
00857 {
00858 if (ev.isGUI()) {
00859 std::stringstream ttString;
00860
00861
00862 ttString << thisNode.getAddress() << " " << thisNode.getKey();
00863
00864 getParentModule()->getParentModule()->getDisplayString().
00865 setTagArg("tt", 0, ttString.str().c_str());
00866 getParentModule()->getDisplayString().
00867 setTagArg("tt", 0, ttString.str().c_str());
00868 getDisplayString().setTagArg("tt", 0, ttString.str().c_str());
00869
00870 }
00871 }
00872
00873 bool Broose::handleRpcCall(BaseCallMessage* msg)
00874 {
00875 if (state == BSET || state == READY) {
00876
00877 RPC_SWITCH_START(msg)
00878 RPC_DELEGATE(Bucket, handleBucketRequestRpc);
00879 RPC_ON_CALL(Ping) {
00880
00881 routingAdd(msg->getSrcNode(), true);
00882 return false;
00883 break;
00884 }
00885 RPC_ON_CALL(FindNode) {
00886
00887 routingAdd(msg->getSrcNode(), true);
00888 return false;
00889 break;
00890 }
00891 RPC_SWITCH_END()
00892 return RPC_HANDLED;
00893 } else {
00894 RPC_SWITCH_START(msg)
00895
00896 RPC_ON_CALL(Ping) {
00897 delete msg;
00898 return true;
00899 break;
00900 }
00901 RPC_ON_CALL(FindNode) {
00902 delete msg;
00903 return true;
00904 break;
00905 }
00906 RPC_SWITCH_END()
00907 return RPC_HANDLED;
00908 }
00909 }
00910
00911 void Broose::handleRpcResponse(BaseResponseMessage* msg,
00912 const RpcState& rpcState,
00913 simtime_t rtt)
00914 {
00915
00916 routingAdd(msg->getSrcNode(), true, rtt);
00917
00918 RPC_SWITCH_START(msg)
00919 RPC_ON_RESPONSE( Bucket ) {
00920 handleBucketResponseRpc(_BucketResponse, rpcState);
00921 EV << "[Broose::handleRpcResponse() @ " << thisNode.getAddress()
00922 << " (" << thisNode.getKey().toString(16) << ")]\n"
00923 << " Bucket RPC Response received: id=" << rpcState.getId() << "\n"
00924 << " msg=" << *_BucketResponse << " rtt=" << rtt
00925 << endl;
00926 break;
00927 }
00928 RPC_ON_RESPONSE(FindNode)
00929 {
00930
00931 for (uint32_t i=0; i<_FindNodeResponse->getClosestNodesArraySize(); i++)
00932 routingAdd(_FindNodeResponse->getClosestNodes(i), false);
00933 break;
00934 }
00935 RPC_SWITCH_END( )
00936 }
00937
00938 void Broose::handleRpcTimeout(const RpcState& rpcState)
00939 {
00940 RPC_SWITCH_START(rpcState.getCallMsg())
00941 RPC_ON_CALL(FindNode) {
00942 handleFindNodeTimeout(_FindNodeCall, rpcState.getDest(), rpcState.getDestKey());
00943 EV << "[Broose::handleRpcTimeout() @ " << thisNode.getAddress()
00944 << " (" << thisNode.getKey().toString(16) << ")]\n"
00945 << " Find Node RPC Call timed out: id=" << rpcState.getId() << "\n"
00946 << " msg=" << *_FindNodeCall
00947 << endl;
00948 break;
00949 }
00950 RPC_ON_CALL(Bucket) {
00951 handleBucketTimeout(_BucketCall);
00952 EV << "[Broose::handleRpcTimeout() @ " << thisNode.getAddress()
00953 << " (" << thisNode.getKey().toString(16) << ")]\n"
00954 << " Bucket RPC Call timed out: id=" << rpcState.getId() << "\n"
00955 << " msg=" << *_BucketCall
00956 << endl;
00957 break;
00958 }
00959 RPC_SWITCH_END()
00960 }
00961
00962 void Broose::handleBucketRequestRpc(BucketCall* msg)
00963 {
00964 if (msg->getBucketType() == LEFT) {
00965
00966
00967 if (stab1 && (state == BSET)) {
00968
00969 delete msg;
00970 return;
00971 }
00972
00973
00974 int size = lBucket->getSize();
00975 BucketResponse* bResponse = new BucketResponse("LBucketResponse");
00976 bResponse->setNodesArraySize(size);
00977
00978 for (int i = 0; i < size; i++) {
00979 bResponse->setNodes(i, lBucket->get(i));
00980 }
00981
00982 bResponse->setBitLength(BUCKETRESPONSE_L(bResponse));
00983
00984
00985
00986
00987
00988 if (stab2 || (msg->getProState() == PBSET)) {
00989 routingAdd(msg->getSrcNode(), true);
00990 }
00991
00992 sendRpcResponse(msg, bResponse);
00993 } else if (msg->getBucketType() == BROTHER) {
00994
00995 int size = bBucket->getSize();
00996 BucketResponse* bResponse = new BucketResponse("BBucketResponse");
00997 bResponse->setNodesArraySize(size);
00998
00999 for (int i = 0; i < size; i++) {
01000 bResponse->setNodes(i, bBucket->get(i));
01001 }
01002 bResponse->setBitLength(BUCKETRESPONSE_L(bResponse));
01003
01004 sendRpcResponse(msg, bResponse);
01005 } else
01006 error("Broose::handleBucketRequestRpc() - Wrong Bucket Type!");
01007 }
01008
01009 void Broose::handleBucketResponseRpc(BucketResponse* msg,
01010 const RpcState& rpcState)
01011 {
01012 BucketCall* call = check_and_cast<BucketCall*>(rpcState.getCallMsg());
01013
01014 for (uint i = 0; i < msg->getNodesArraySize(); i++) {
01015 routingAdd(msg->getNodes(i), false);
01016 }
01017
01018 if (call->getBucketType() == LEFT) {
01019 switch (state) {
01020 case RSET:
01021 if (call->getProState() == PRSET) {
01022 receivedBBucketLookup++;
01023
01024 if (receivedBBucketLookup == numberBBucketLookup)
01025 changeState(BSET);
01026 }
01027 break;
01028 case BSET:
01029 if (call->getProState() == PBSET) {
01030 receivedLBucketLookup++;
01031
01032 if (receivedLBucketLookup == numberLBucketLookup)
01033 changeState(READY);
01034 }
01035 break;
01036 default:
01037 break;
01038 }
01039 } else if (call->getBucketType() == BROTHER) {
01040 switch(state) {
01041 case INIT:
01042 if (call->getProState() == PINIT) {
01043 receivedJoinResponse++;
01044 if (receivedJoinResponse == powShiftingBits)
01045 changeState(RSET);
01046 }
01047 default:
01048 break;
01049 }
01050 } else
01051 error("Broose::handleBucketRequestRpc() - unknown error.");
01052 }
01053
01054
01055 void Broose::handleBucketTimeout(BucketCall* msg)
01056 {
01057 if (state == READY)
01058 return;
01059 else {
01060 bucketRetries++;
01061 changeState(INIT);
01062 }
01063 }
01064
01065 void Broose::pingResponse(PingResponse* pingResponse, cPolymorphic* context,
01066 int rpcId, simtime_t rtt) {
01067
01068 routingAdd(pingResponse->getSrcNode(), true, rtt);
01069 }
01070
01071 void Broose::routingTimeout(const BrooseHandle& handle)
01072 {
01073 for (size_t i = 0; i < bucketVector.size(); i++) {
01074 if (bucketVector[i]->getFailedResponses(handle) == numberRetries)
01075 bucketVector[i]->remove(handle);
01076 else
01077 bucketVector[i]->increaseFailedResponses(handle);
01078 }
01079
01080
01081 }
01082
01083 void Broose::handleFindNodeTimeout(FindNodeCall* findNode,
01084 const TransportAddress& dest,
01085 const OverlayKey& destKey)
01086 {
01087 routingTimeout(dynamic_cast<const NodeHandle&>(dest));
01088 }
01089
01090 void Broose::pingTimeout(PingCall* pingCall,
01091 const TransportAddress& dest,
01092 cPolymorphic* context, int rpcId)
01093 {
01094 routingTimeout(dynamic_cast<const NodeHandle&>(dest));
01095 }
01096
01097 bool Broose::routingAdd(const NodeHandle& node, bool isAlive,
01098 simtime_t rtt)
01099 {
01100 bool added = false;
01101
01102 for (size_t i = 0; i < bucketVector.size(); i++) {
01103 added |= bucketVector[i]->add(node, isAlive, rtt);
01104 }
01105
01106 return added;
01107 }
01108
01109 void Broose::setLastSeen(const NodeHandle& node)
01110 {
01111 for (size_t i = 0; i < bucketVector.size(); i++) {
01112 bucketVector[i]->setLastSeen(node, simTime());
01113 }
01114 }
01115
01116 void Broose::addNode(const NodeHandle& node)
01117 {
01118
01119 for (size_t i = 0; i < bucketVector.size(); i++) {
01120 bucketVector[i]->add(node);
01121 }
01122 }
01123
01124 void Broose::resetFailedResponses(const NodeHandle& node)
01125 {
01126 for (size_t i = 0; i < bucketVector.size(); i++) {
01127 bucketVector[i]->resetFailedResponses(node);
01128 }
01129 }
01130
01131 void Broose::setRTT(const NodeHandle& node, simtime_t rtt)
01132 {
01133 for (size_t i = 0; i < bucketVector.size(); i++) {
01134 bucketVector[i]->setRTT(node, rtt);
01135 }
01136 }
01137
01138