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
bool stab1
bool stab2
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 1116 of file Broose.cc.

Referenced by findNode().

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

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

changes the node's state

Parameters:
state the state to which a node is changing

Definition at line 145 of file Broose.cc.

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

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

void Broose::displayBucketState (  )  [protected]

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

Definition at line 805 of file Broose.cc.

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 }

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 574 of file Broose.cc.

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

void Broose::finishOverlay (  )  [virtual]

collects statistical data in derived class

Reimplemented from BaseOverlay.

Definition at line 772 of file Broose.cc.

00773 {
00774     // store statistics
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 }

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 351 of file Broose.cc.

00352 {
00353     return bucketSize;
00354 }

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 346 of file Broose.cc.

Referenced by isSiblingFor().

00347 {
00348     return bucketSize;
00349 }

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 356 of file Broose.cc.

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

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

handles a received Bucket request

Parameters:
msg the message to process

Definition at line 962 of file Broose.cc.

Referenced by handleRpcCall().

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

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 1009 of file Broose.cc.

Referenced by handleRpcResponse().

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 }

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

handles a received Bucket timeout

Parameters:
msg the message to process

Definition at line 1055 of file Broose.cc.

Referenced by handleRpcTimeout().

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

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

handles a expired bucket refresh timer

Parameters:
msg the bucket refresh self-message

Definition at line 318 of file Broose.cc.

Referenced by handleTimerEvent().

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 }

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 1083 of file Broose.cc.

Referenced by handleRpcTimeout().

01086 {
01087     routingTimeout(dynamic_cast<const NodeHandle&>(dest));
01088 }

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

handles a expired join timer

Parameters:
msg the timer self-message

Definition at line 268 of file Broose.cc.

Referenced by handleTimerEvent().

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

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 873 of file Broose.cc.

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

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 911 of file Broose.cc.

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

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 938 of file Broose.cc.

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 }

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

Reimplemented from BaseRpc.

Definition at line 258 of file Broose.cc.

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 }

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     stab1 = par("stab1");
00085     stab2 = par("stab2");
00086 
00087     //statistics
00088     bucketCount = 0;
00089     bucketBytesSent = 0;
00090 
00091     //init local parameters
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     // add some watches
00104     WATCH(receivedJoinResponse);
00105     WATCH(receivedBBucketLookup);
00106     WATCH(numberBBucketLookup);
00107     WATCH(receivedLBucketLookup);
00108     WATCH(numberLBucketLookup);
00109     WATCH(state);
00110 
00111     // get module pointers for all buckets
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     // create join and bucket timer
00129     join_timer = new cMessage("join_timer");
00130     bucket_timer = new cMessage("bucket_timer");
00131 }

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 823 of file Broose.cc.

Referenced by findNode().

00827 {
00828 // TODO: node != thisNode doesn't work yet
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     // set default number of siblings to consider
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     // TODO: handle numSibling parameter
00853     return bBucket->keyInRange(key);
00854 }

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 133 of file Broose.cc.

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

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

Reimplemented from BaseRpc.

Definition at line 1065 of file Broose.cc.

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

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

Reimplemented from BaseRpc.

Definition at line 1090 of file Broose.cc.

01093 {
01094     routingTimeout(dynamic_cast<const NodeHandle&>(dest));
01095 }

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 785 of file Broose.cc.

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 }

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

resets the counter of failed responses

Parameters:
node node handle of the responding node

Definition at line 1124 of file Broose.cc.

01125 {
01126     for (size_t i = 0; i < bucketVector.size(); i++) {
01127         bucketVector[i]->resetFailedResponses(node);
01128     }
01129 }

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 1097 of file Broose.cc.

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

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 }

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

Definition at line 1071 of file Broose.cc.

Referenced by handleFindNodeTimeout(), and pingTimeout().

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     // TODO: if we loose the last node (despite ourself) from the
01080     //       B bucket, we should call join() to rejoin the network
01081 }

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 1109 of file Broose.cc.

Referenced by findNode().

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

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 1131 of file Broose.cc.

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

void Broose::updateTooltip (  ) 

updates information shown in tk-environment

Definition at line 856 of file Broose.cc.

Referenced by changeState().

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


Friends And Related Function Documentation

friend class BrooseBucket [friend]

Definition at line 273 of file Broose.h.

Referenced by changeState(), and handleBucketTimerExpired().


Member Data Documentation

node handle holding the bootstrap node

Definition at line 124 of file Broose.h.

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

cMessage* Broose::bucket_timer [protected]

timer to reconstruct all buckets

Definition at line 121 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 110 of file Broose.h.

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

int Broose::bucketCount [protected]

number of Bucket messages

Definition at line 109 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 120 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 111 of file Broose.h.

Referenced by finishOverlay(), and initializeOverlay().

int Broose::powShiftingBits [protected]

Definition at line 115 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().

bool Broose::stab1 [protected]

Definition at line 105 of file Broose.h.

Referenced by handleBucketRequestRpc(), and initializeOverlay().

bool Broose::stab2 [protected]

Definition at line 106 of file Broose.h.

Referenced by handleBucketRequestRpc(), 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 Wed May 26 16:21:16 2010 for OverSim by  doxygen 1.6.3