Broose Class Reference

Broose overlay module. More...

#include <Broose.h>

Inheritance diagram for Broose:

BaseOverlay BaseRpc TopologyVis RpcListener

List of all members.

Public Member Functions

 Broose ()
 ~Broose ()
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void finishOverlay ()
 collects statistical data in derived class
virtual bool isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err)
 Query if a node is among the siblings for a given key.
virtual void joinOverlay ()
 Join the overlay with a given nodeID in thisNode.key.
virtual void recordOverlaySentStats (BaseOverlayMessage *msg)
 Collect overlay specific sent messages statistics.
virtual bool handleRpcCall (BaseCallMessage *msg)
 Processes Remote-Procedure-Call invocation messages.
virtual void handleTimerEvent (cMessage *msg)
void updateTooltip ()
 updates information shown in tk-environment

Protected Member Functions

void handleJoinTimerExpired (cMessage *msg)
 handles a expired join timer
void handleBucketTimerExpired (cMessage *msg)
 handles a expired bucket refresh timer
int getRoutingDistance (const OverlayKey &key, const OverlayKey &node, int dist)
 calculates the de-buijn distance between a key and a nodeId
bool routingAdd (const NodeHandle &node, bool isAlive, simtime_t rtt=MAXTIME)
 Adds a node to the routing table.
void changeState (int state)
 changes the node's state
NodeVectorfindNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg)
 Implements the find node call.
int getMaxNumSiblings ()
 Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.
int getMaxNumRedundantNodes ()
 Query the maximum number of redundant next hop nodes that are returned by findNode().
void displayBucketState ()
 debug function which output the content of the node's buckets
void handleRpcResponse (BaseResponseMessage *msg, const RpcState &rpcState, simtime_t rtt)
 This method is called if an RPC response has been received.
void handleRpcTimeout (const RpcState &rpcState)
 This method is called if an RPC timeout has been reached.
void handleFindNodeTimeout (FindNodeCall *findNode, const TransportAddress &dest, const OverlayKey &destKey)
 This method is called if an Find Node Call timeout has been reached.
void handleBucketRequestRpc (BucketCall *msg)
 handles a received Bucket request
void handleBucketResponseRpc (BucketResponse *msg, const RpcState &rpcState)
 handles a received Bucket response
void handleBucketTimeout (BucketCall *msg)
 handles a received Bucket timeout
void routingTimeout (const BrooseHandle &handle)
virtual void pingResponse (PingResponse *pingResponse, cPolymorphic *context, int rpcId, simtime_t rtt)
virtual void pingTimeout (PingCall *pingCall, const TransportAddress &dest, cPolymorphic *context, int rpcId)
void setLastSeen (const NodeHandle &node)
 updates the timestamp of a node in all buckets
void addNode (const NodeHandle &node)
 adds a node to all buckets
void resetFailedResponses (const NodeHandle &node)
 resets the counter of failed responses
void setRTT (const NodeHandle &node, simtime_t rtt)
 sets the rtt to a node in all buckets

Protected Attributes

int chooseLookup
 decides which kind of lookup (right/left shifting) is used
simtime_t joinDelay
 time interval between two join tries
int receivedJoinResponse
 number of received join response messages
int receivedBBucketLookup
 number of received lookup responses for the B bucket
int numberBBucketLookup
 maximal number of lookup responses for the B bucket
int receivedLBucketLookup
 number of received lookup responses for the L bucket
int numberLBucketLookup
 maximal number of lookup responses for the L bucket
int shiftingBits
 number of bits shifted in/out each step
int powShiftingBits
 2^{variable shiftingBits}
uint32_t bucketSize
 maximal number of bucket entries
uint32_t rBucketSize
 maximal number of entries in the r buckets
int keyLength
 length of the node and data IDs
simtime_t refreshTime
 idle time after which a node is pinged
uint32_t userDist
 how many hops are added to the estimated hop count
int numberRetries
 number of retries in case of timeout
int bucketRetries
 number of bucket retries for a successful join
int bucketCount
 number of Bucket messages
int bucketBytesSent
 length of all Bucket messages
int numFailedPackets
 number of packets which couldn't be routed correctly
BrooseBucketlBucket
BrooseBucketbBucket
BrooseBucket ** rBucket
std::vector< BrooseBucket * > bucketVector
 vector of all Broose buckets
cMessage * join_timer
cMessage * bucket_timer
 timer to reconstruct all buckets
TransportAddress bootstrapNode
 node handle holding the bootstrap node

Friends

class BrooseBucket


Detailed Description

Broose overlay module.

Implementation of the Broose KBR overlay as described in "Broose: A Practical Distributed Hashtable Based on the De-Bruijn Topology" by Anh-Tuan Gai and Laurent Viennot

Author:
Jochen Schenk
See also:
Bucket

Definition at line 52 of file Broose.h.


Constructor & Destructor Documentation

Broose::Broose (  ) 

Definition at line 51 of file Broose.cc.

00052 {
00053     join_timer = NULL;
00054     bucket_timer = NULL;
00055     rBucket = NULL;
00056     lBucket = NULL;
00057     bBucket =  NULL;
00058 }

Broose::~Broose (  ) 

Definition at line 59 of file Broose.cc.

00060 {
00061     // delete timers
00062     cancelAndDelete(join_timer);
00063     cancelAndDelete(bucket_timer);
00064 }


Member Function Documentation

void Broose::addNode ( const NodeHandle node  )  [protected]

adds a node to all buckets

Parameters:
node node handle which should be added

Definition at line 1113 of file Broose.cc.

Referenced by findNode().

01114 {
01115     // add node to all buckets
01116     for (size_t i = 0; i < bucketVector.size(); i++) {
01117         bucketVector[i]->add(node);
01118     }
01119 }

void Broose::changeState ( int  state  )  [protected]

changes the node's state

Parameters:
state the state to which a node is changing

Definition at line 143 of file Broose.cc.

Referenced by handleBucketResponseRpc(), handleBucketTimeout(), handleJoinTimerExpired(), and joinOverlay().

00144 {
00145     switch (toState) {
00146     case INIT: {
00147         state = INIT;
00148 
00149         // find a new bootstrap node and enroll to the bootstrap list
00150         bootstrapNode = bootstrapList->getBootstrapNode();
00151 
00152         cancelEvent(join_timer);
00153         scheduleAt(simTime(), join_timer);
00154 
00155         // initialize respectively clear the buckets
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         // if we have restarted the join protocol reset parameters
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         // half of the calls must return for a state change
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         // half of the calls must return for a state change
00212         numberLBucketLookup = ceil((double)bBucket->getSize() / 2);
00213 
00214         // send messages to all entries of the B Bucket
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         // fill the bucket also with this node
00235         for (size_t i = 0; i < bucketVector.size(); i++) {
00236             bucketVector[i]->add(thisNode);
00237         }
00238 
00239         // to disable the ping protocol a pingDelay or
00240         // refreshTime of zero was given
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 }

void Broose::displayBucketState (  )  [protected]

debug function which output the content of the node's buckets

Definition at line 803 of file Broose.cc.

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 }

NodeVector * Broose::findNode ( const OverlayKey key,
int  numRedundantNodes,
int  numSiblings,
BaseOverlayMessage msg 
) [protected, virtual]

Implements the find node call.

This method simply returns the closest nodes known in the corresponding routing topology. If the node is a sibling for this key (isSiblingFor(key) = true), this method returns all numSiblings siblings, with the closest neighbor to the key first.

Parameters:
key The lookup key.
numRedundantNodes Maximum number of next hop nodes to return.
numSiblings number of siblings to return
msg A pointer to the BaseRouteMessage or FindNodeCall message of this lookup.
Returns:
NodeVector with closest nodes.

Reimplemented from BaseOverlay.

Definition at line 572 of file Broose.cc.

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         // exhaustive iterative doesn't care about siblings
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         //return the closest nodes
00597         // sort with XOR distance to key
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         std::cout << "key: " << key.toString(2).substr(0, 8)
00609                   << " ThisNode: " << thisNode.getKey().toString(2).substr(0, 8);
00610         if (result->size() > 0) {
00611             std::cout << " next hop (final): " << (*result)[0].getKey().toString(2).substr(0, 8);
00612         } else {
00613             std::cout << " no next hop! (final)";
00614         }
00615         std::cout << std::endl << std::endl;
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             // estimate distance
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                 // init left shifting lookup
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                 // init right shifting lookup
00657                 findNodeExt->setRightShifting(true);
00658             }
00659 
00660             //add contact for next Hop
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     // update buckets with last hop
00673     addNode(findNodeExt->getLastNode());
00674     setLastSeen(findNodeExt->getLastNode());
00675 
00676     // replace last hop contact information with
00677     // this hop contact information
00678     findNodeExt->setLastNode(thisNode);
00679 
00680     // brother lookup
00681     if (findNodeExt->getStep() == 0) {
00682         // return the closest nodes sorted by XOR distance to key
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         // Left Shifting Lookup
00696 
00697         // can't handle left shifting lookup in BSET-State
00698         if (state == BSET)
00699             return result;
00700 
00701         // calculate routing key
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         std::cout << "key: " << key.toString(2).substr(0, 8)
00715                   << " dist: " << findNodeExt->getStep()
00716                   << " rtkey: " << findNodeExt->getRouteKey().toString(2).substr(0, 8)
00717                   << " ThisNode: " << thisNode.getKey().toString(2).substr(0, 8);
00718         if (result->size() > 0) {
00719             std::cout << " next hop: " << (*result)[0].getKey().toString(2).substr(0, 8);
00720         } else {
00721             std::cout << " no next hop!";
00722         }
00723         std::cout << std::endl << std::endl;
00724         */
00725 
00726     } else {
00727         // Right Shifting Lookup
00728 
00729 
00730         // calculate routing key
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         std::cout << "key: " << key.toString(2).substr(0, 8)
00751                   << " dist: " << findNodeExt->getStep()
00752                   << " rtkey: " << findNodeExt->getRouteKey().toString(2).substr(0, 8)
00753                   << " ThisNode: " << thisNode.getKey().toString(2).substr(0, 8);
00754         if (result->size() > 0) {
00755             std::cout << " next hop: " << (*result)[0].getKey().toString(2).substr(0, 8);
00756         } else {
00757             std::cout << " no next hop!";
00758         }
00759         std::cout << std::endl << std::endl;
00760         */
00761     }
00762 
00763     if ((*result)[0] == thisNode) {
00764         delete result;
00765         return (findNode(key, numRedundantNodes, numSiblings, msg));
00766     } else
00767         return result;
00768 }

void Broose::finishOverlay (  )  [virtual]

collects statistical data in derived class

Reimplemented from BaseOverlay.

Definition at line 770 of file Broose.cc.

00771 {
00772     // store statistics
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 }

int Broose::getMaxNumRedundantNodes (  )  [protected, virtual]

Query the maximum number of redundant next hop nodes that are returned by findNode().

Returns:
int number of redundant nodes returned by findNode().

Reimplemented from BaseOverlay.

Definition at line 349 of file Broose.cc.

00350 {
00351     return bucketSize;
00352 }

int Broose::getMaxNumSiblings (  )  [protected, virtual]

Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.

Returns:
int number of siblings.

Reimplemented from BaseOverlay.

Definition at line 344 of file Broose.cc.

Referenced by isSiblingFor().

00345 {
00346     return bucketSize;
00347 }

int Broose::getRoutingDistance ( const OverlayKey key,
const OverlayKey node,
int  dist 
) [protected]

calculates the de-buijn distance between a key and a nodeId

Parameters:
key the overlay key
node the nodeId
dist the estimated maximum distance based on the number of nodes in the system
Returns:
the number of routing steps to the destination (negative for left shifting lookups)

Definition at line 354 of file Broose.cc.

00356 {
00357     for (uint i = 0; i < (uint)abs(dist); i++) {
00358         if (node.sharedPrefixLength(key << i) >= (abs(dist) - i)) {
00359              return i; // right shifting
00360          }
00361         if (key.sharedPrefixLength(node << i) >= (abs(dist) - i)) {
00362             return -i; // left shifting
00363         }
00364     }
00365 
00366     if (((chooseLookup++) % 2) == 0) {
00367         return -dist;
00368     } else {
00369         return dist;
00370     }
00371 }

void Broose::handleBucketRequestRpc ( BucketCall msg  )  [protected]

handles a received Bucket request

Parameters:
msg the message to process

Definition at line 959 of file Broose.cc.

Referenced by handleRpcCall().

00960 {
00961     if (msg->getBucketType() == LEFT) {
00962 #if 0
00963         // TODO: dependent on the churn scenarios this may give better
00964         //       or worse results
00965         if (state == BSET) {
00966             // can't handle LBucketRequest in BSET-State
00967             delete msg;
00968             return;
00969         }
00970 #endif
00971 
00972         // return L-Bucket
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         // only add, if the originator is already in the BSET state
00984         // in which the node already is able to do right shifting lookups
00985         // TODO: this leads to lower lookup success rates in some scenarios
00986         //       but helps to prevent deadlock situations with high churn rates
00987         if (msg->getProState() == PBSET) {
00988             routingAdd(msg->getSrcNode(), true);
00989         }
00990 
00991         sendRpcResponse(msg, bResponse);
00992     } else if (msg->getBucketType() == BROTHER) {
00993         // return B-Bucket
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 }

void Broose::handleBucketResponseRpc ( BucketResponse msg,
const RpcState rpcState 
) [protected]

handles a received Bucket response

Parameters:
msg the message to process
rpcState the state object for the received RPC

Definition at line 1008 of file Broose.cc.

Referenced by handleRpcResponse().

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 }

void Broose::handleBucketTimeout ( BucketCall msg  )  [protected]

handles a received Bucket timeout

Parameters:
msg the message to process

Definition at line 1054 of file Broose.cc.

Referenced by handleRpcTimeout().

01055 {
01056     if (state == READY)
01057         return;
01058     else {
01059         bucketRetries++;
01060         changeState(INIT);
01061     }
01062 }

void Broose::handleBucketTimerExpired ( cMessage *  msg  )  [protected]

handles a expired bucket refresh timer

Parameters:
msg the bucket refresh self-message

Definition at line 316 of file Broose.cc.

Referenced by handleTimerEvent().

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 }

void Broose::handleFindNodeTimeout ( FindNodeCall findNode,
const TransportAddress dest,
const OverlayKey destKey 
) [protected]

This method is called if an Find Node Call timeout has been reached.

Parameters:
findNode The original FindNodeCall
dest the destination node
destKey the destination OverlayKey

Definition at line 1080 of file Broose.cc.

Referenced by handleRpcTimeout().

01083 {
01084     routingTimeout(dynamic_cast<const NodeHandle&>(dest));
01085 }

void Broose::handleJoinTimerExpired ( cMessage *  msg  )  [protected]

handles a expired join timer

Parameters:
msg the timer self-message

Definition at line 266 of file Broose.cc.

Referenced by handleTimerEvent().

00267 {
00268     if (state == READY)
00269         return;
00270 
00271     if (!bootstrapNode.isUnspecified()) {
00272         // create new lookup message
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         // do lookups for key >> shiftingBits for each prefix
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             // restart join protocol if one call times out
00303             // otherwise the node might be isolated
00304             sendRouteRpcCall(OVERLAY_COMP, bootstrapNode, add,
00305                              bCallArray[i]);
00306         }
00307         //createLookup()->lookup(getThisNode().getKey() + 1, 0, 0, 0,
00308         //                       new BrooseLookupListener(this));
00309     } else {
00310         // if the bootstrap node is unspecified we are the only node in the network
00311         // so we can skip the "normal" join protocol
00312         changeState(READY);
00313     }
00314 }

bool Broose::handleRpcCall ( BaseCallMessage msg  )  [virtual]

Processes Remote-Procedure-Call invocation messages.


This method should be overloaded when the overlay provides RPC functionality.

Returns:
true, if rpc has been handled

Reimplemented from BaseRpc.

Definition at line 870 of file Broose.cc.

00871 {
00872     if (state == BSET || state == READY) {
00873         // delegate messages
00874         RPC_SWITCH_START(msg)
00875         RPC_DELEGATE(Bucket, handleBucketRequestRpc);
00876         RPC_ON_CALL(Ping) {
00877             // add pinging node to all buckets and update lastSeen of node
00878             routingAdd(msg->getSrcNode(), true);
00879             return false;
00880             break;
00881         }
00882         RPC_ON_CALL(FindNode) {
00883             // add pinging node to all buckets and update lastSeen of node
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         // don't answer PING and FIND_NODE calls, if the node can't route yet
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 }

void Broose::handleRpcResponse ( BaseResponseMessage msg,
const RpcState rpcState,
simtime_t  rtt 
) [protected, virtual]

This method is called if an RPC response has been received.

Parameters:
msg The response message.
rpcState Reference to an RpcState object containing e.g. the original call message, the destination (TransportAddress and/or OverlayKey), a context pointer, ...
rtt The round-trip time of this RPC

Reimplemented from RpcListener.

Definition at line 908 of file Broose.cc.

00911 {
00912     // add sender to all buckets and update lastSeen of node
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         // add inactive nodes
00928         for (uint32_t i=0; i<_FindNodeResponse->getClosestNodesArraySize(); i++)
00929             routingAdd(_FindNodeResponse->getClosestNodes(i), false);
00930         break;
00931     }
00932     RPC_SWITCH_END( )
00933 }

void Broose::handleRpcTimeout ( const RpcState rpcState  )  [protected, virtual]

This method is called if an RPC timeout has been reached.

Parameters:
rpcState Reference to an RpcState object containing e.g. the original call message, the destination (TransportAddress and/or OverlayKey), a context pointer, ...

Reimplemented from RpcListener.

Definition at line 935 of file Broose.cc.

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 }

void Broose::handleTimerEvent ( cMessage *  msg  )  [virtual]

Reimplemented from BaseRpc.

Definition at line 256 of file Broose.cc.

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 }

void Broose::initializeOverlay ( int  stage  )  [virtual]

Initializes derived-class-attributes.


Initializes derived-class-attributes, called by BaseOverlay::initialize(). By default this method is called once. If more stages are needed one can overload numInitStages() and add more stages.

Parameters:
stage the init stage

Reimplemented from BaseOverlay.

Definition at line 66 of file Broose.cc.

00067 {
00068     // because of IPAddressResolver, we need to wait until interfaces
00069     // are registered, address auto-assignment takes place etc.
00070     if (stage != MIN_STAGE_OVERLAY)
00071         return;
00072 
00073     // Broose provides KBR services
00074     kbr = true;
00075 
00076     // fetch some parameters
00077     bucketSize = par("bucketSize"); // = k
00078     rBucketSize = par("rBucketSize"); // = k'
00079     joinDelay = par("joinDelay");
00080     shiftingBits = par("brooseShiftingBits");
00081     userDist = par("userDist");
00082     refreshTime = par("refreshTime");
00083     numberRetries = par("numberRetries");
00084 
00085     //statistics
00086     bucketCount = 0;
00087     bucketBytesSent = 0;
00088 
00089     //init local parameters
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     // add some watches
00102     WATCH(receivedJoinResponse);
00103     WATCH(receivedBBucketLookup);
00104     WATCH(numberBBucketLookup);
00105     WATCH(receivedLBucketLookup);
00106     WATCH(numberLBucketLookup);
00107     WATCH(state);
00108 
00109     // get module pointers for all buckets
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     // create join and bucket timer
00127     join_timer = new cMessage("join_timer");
00128     bucket_timer = new cMessage("bucket_timer");
00129 }

bool Broose::isSiblingFor ( const NodeHandle node,
const OverlayKey key,
int  numSiblings,
bool *  err 
) [virtual]

Query if a node is among the siblings for a given key.

Query if a node is among the siblings for a given key. This means, that the nodeId of this node is among the closest numSiblings nodes to the key and that by a local findNode() call all other siblings to this key can be retrieved.

Parameters:
node the NodeHandle
key destination key
numSiblings The nodes knows all numSiblings nodes close to this key
err return false if the range could not be determined
Returns:
bool true, if the node is responsible for the key.

Reimplemented from BaseOverlay.

Definition at line 821 of file Broose.cc.

Referenced by findNode().

00825 {
00826 // TODO: node != thisNode doesn't work yet
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     // set default number of siblings to consider
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 }

void Broose::joinOverlay (  )  [virtual]

Join the overlay with a given nodeID in thisNode.key.

Join the overlay with a given nodeID in thisNode.key. This method may be called by an application to join the overlay with a specific nodeID. It is also called if the node's IP address changes.

Reimplemented from BaseOverlay.

Definition at line 131 of file Broose.cc.

00132 {
00133     changeState(INIT);
00134 
00135     // if the bootstrap node is unspecified we are the only node in the network
00136     // so we can skip the "normal" join protocol
00137     if (bootstrapNode.isUnspecified()) {
00138         changeState(READY);
00139     }
00140 }

void Broose::pingResponse ( PingResponse pingResponse,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

Reimplemented from BaseRpc.

Definition at line 1064 of file Broose.cc.

01065                                                     {
01066     // if node respond reset failedResponses and add lastSeen to node
01067     routingAdd(pingResponse->getSrcNode(), true, rtt);
01068 }

void Broose::pingTimeout ( PingCall pingCall,
const TransportAddress dest,
cPolymorphic *  context,
int  rpcId 
) [protected, virtual]

Reimplemented from BaseRpc.

Definition at line 1087 of file Broose.cc.

01090 {
01091     routingTimeout(dynamic_cast<const NodeHandle&>(dest));
01092 }

void Broose::recordOverlaySentStats ( BaseOverlayMessage msg  )  [virtual]

Collect overlay specific sent messages statistics.

This method is called from BaseOverlay::sendMessageToUDP() for every overlay message that is sent by a node. Use this to collect statistical data for overlay protocol specific message types.

Parameters:
msg The overlay message to be sent to the UDP layer

Reimplemented from BaseOverlay.

Definition at line 783 of file Broose.cc.

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 }

void Broose::resetFailedResponses ( const NodeHandle node  )  [protected]

resets the counter of failed responses

Parameters:
node node handle of the responding node

Definition at line 1121 of file Broose.cc.

01122 {
01123     for (size_t i = 0; i < bucketVector.size(); i++) {
01124         bucketVector[i]->resetFailedResponses(node);
01125     }
01126 }

bool Broose::routingAdd ( const NodeHandle node,
bool  isAlive,
simtime_t  rtt = MAXTIME 
) [protected]

Adds a node to the routing table.

Parameters:
node NodeHandle to add
isAlive true, if it is known that the node is alive
rtt measured round-trip-time to node
Returns:
true, if the node was known or has been added

Definition at line 1094 of file Broose.cc.

Referenced by handleBucketRequestRpc(), handleBucketResponseRpc(), handleRpcCall(), handleRpcResponse(), and pingResponse().

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 }

void Broose::routingTimeout ( const BrooseHandle handle  )  [protected]

Definition at line 1070 of file Broose.cc.

Referenced by handleFindNodeTimeout(), and pingTimeout().

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 }

void Broose::setLastSeen ( const NodeHandle node  )  [protected]

updates the timestamp of a node in all buckets

Parameters:
node node handle which should be updated

Definition at line 1106 of file Broose.cc.

Referenced by findNode().

01107 {
01108     for (size_t i = 0; i < bucketVector.size(); i++) {
01109         bucketVector[i]->setLastSeen(node, simTime());
01110     }
01111 }

void Broose::setRTT ( const NodeHandle node,
simtime_t  rtt 
) [protected]

sets the rtt to a node in all buckets

Parameters:
node node handle to which a rtt is added/updated
rtt round trip time to the node

Definition at line 1128 of file Broose.cc.

01129 {
01130     for (size_t i = 0; i < bucketVector.size(); i++) {
01131         bucketVector[i]->setRTT(node, rtt);
01132     }
01133 }

void Broose::updateTooltip (  ) 

updates information shown in tk-environment

Definition at line 853 of file Broose.cc.

Referenced by changeState().

00854 {
00855     if (ev.isGUI()) {
00856         std::stringstream ttString;
00857 
00858         // show our ip and key in tooltip
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 }


Friends And Related Function Documentation

friend class BrooseBucket [friend]

Definition at line 271 of file Broose.h.

Referenced by changeState(), and handleBucketTimerExpired().


Member Data Documentation

node handle holding the bootstrap node

Definition at line 122 of file Broose.h.

Referenced by changeState(), handleJoinTimerExpired(), and joinOverlay().

cMessage* Broose::bucket_timer [protected]

timer to reconstruct all buckets

Definition at line 119 of file Broose.h.

Referenced by Broose(), changeState(), handleBucketTimerExpired(), handleTimerEvent(), initializeOverlay(), and ~Broose().

int Broose::bucketBytesSent [protected]

length of all Bucket messages

Definition at line 108 of file Broose.h.

Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().

int Broose::bucketCount [protected]

number of Bucket messages

Definition at line 107 of file Broose.h.

Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().

int Broose::bucketRetries [protected]

number of bucket retries for a successful join

Definition at line 104 of file Broose.h.

Referenced by finishOverlay(), handleBucketTimeout(), and initializeOverlay().

uint32_t Broose::bucketSize [protected]

maximal number of bucket entries

Definition at line 98 of file Broose.h.

Referenced by changeState(), getMaxNumRedundantNodes(), getMaxNumSiblings(), handleBucketTimerExpired(), and initializeOverlay().

std::vector<BrooseBucket*> Broose::bucketVector [protected]

int Broose::chooseLookup [protected]

decides which kind of lookup (right/left shifting) is used

Definition at line 89 of file Broose.h.

Referenced by findNode(), getRoutingDistance(), and initializeOverlay().

cMessage* Broose::join_timer [protected]

Definition at line 118 of file Broose.h.

Referenced by Broose(), changeState(), handleTimerEvent(), initializeOverlay(), and ~Broose().

simtime_t Broose::joinDelay [protected]

time interval between two join tries

Definition at line 90 of file Broose.h.

Referenced by initializeOverlay().

int Broose::keyLength [protected]

length of the node and data IDs

Definition at line 100 of file Broose.h.

Referenced by findNode(), handleJoinTimerExpired(), and initializeOverlay().

int Broose::numberBBucketLookup [protected]

maximal number of lookup responses for the B bucket

Definition at line 93 of file Broose.h.

Referenced by changeState(), handleBucketResponseRpc(), and initializeOverlay().

int Broose::numberLBucketLookup [protected]

maximal number of lookup responses for the L bucket

Definition at line 95 of file Broose.h.

Referenced by changeState(), handleBucketResponseRpc(), and initializeOverlay().

int Broose::numberRetries [protected]

number of retries in case of timeout

Definition at line 103 of file Broose.h.

Referenced by initializeOverlay(), and routingTimeout().

int Broose::numFailedPackets [protected]

number of packets which couldn't be routed correctly

Definition at line 109 of file Broose.h.

Referenced by finishOverlay(), and initializeOverlay().

int Broose::powShiftingBits [protected]

Definition at line 113 of file Broose.h.

Referenced by Broose(), changeState(), displayBucketState(), findNode(), and initializeOverlay().

uint32_t Broose::rBucketSize [protected]

maximal number of entries in the r buckets

Definition at line 99 of file Broose.h.

Referenced by changeState(), handleBucketTimerExpired(), and initializeOverlay().

number of received lookup responses for the B bucket

Definition at line 92 of file Broose.h.

Referenced by changeState(), handleBucketResponseRpc(), and initializeOverlay().

number of received join response messages

Definition at line 91 of file Broose.h.

Referenced by changeState(), handleBucketResponseRpc(), and initializeOverlay().

number of received lookup responses for the L bucket

Definition at line 94 of file Broose.h.

Referenced by changeState(), handleBucketResponseRpc(), and initializeOverlay().

simtime_t Broose::refreshTime [protected]

idle time after which a node is pinged

Definition at line 101 of file Broose.h.

Referenced by changeState(), handleBucketTimerExpired(), and initializeOverlay().

int Broose::shiftingBits [protected]

number of bits shifted in/out each step

Definition at line 96 of file Broose.h.

Referenced by changeState(), handleJoinTimerExpired(), and initializeOverlay().

uint32_t Broose::userDist [protected]

how many hops are added to the estimated hop count

Definition at line 102 of file Broose.h.

Referenced by findNode(), and initializeOverlay().


The documentation for this class was generated from the following files:

Generated on Tue Sep 8 17:26:57 2009 for OverSim by  doxygen 1.5.8