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