Broose Class Reference

#include <Broose.h>

Inheritance diagram for Broose:

BaseOverlay BaseRpc RpcListener List of all members.

Public Member Functions

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 handleUDPMessage (BaseOverlayMessage *msg)
 Processes messages from underlay.
virtual void recordOverlaySentStats (BaseOverlayMessage *msg)
 Collect overlay specific sent messages statistics.
virtual bool handleRpc (BaseCallMessage *msg)
 Processes Remote-Procedure-Call invokation messages.
virtual void handleTimerEvent (cMessage *msg)
 Processes "timer" self-messages.
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
void changeState (int state)
 changes the node's state
NodeVectorfindNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg)
 Implements the find node call.
bool keyBelongsToNode (const OverlayKey &key)
 decides if a specific key is managed by this node
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 binaryOutput (const OverlayKey &key)
 outputs an Overlay key in the binary system
void handleRpcResponse (BaseResponseMessage *msg, int rpcId, simtime_t rtt)
 This method is called if an RPC response has been received.
void handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, int rpcId, const OverlayKey &destKey)
 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)
 handles a received Bucket response
void handleBucketTimeout (BucketCall *msg)
 handles a received Bucket timeout
void handleBroosePingRequestRpc (BroosePingCall *msg)
 handles a received Ping request
void handleBroosePingResponseRpc (BroosePingResponse *msg, simtime_t rtt)
 handles a received Ping response
void handleBroosePingTimeout (BroosePingCall *msg, const TransportAddress &dest, const OverlayKey &destKey)
 handles a received Ping timeout
void setLastSeen (NodeHandle node)
 updates the timestamp of a node in all buckets
void addNode (NodeHandle node, int bucket=0)
 adds a node to all buckets
void resetFailedResponses (NodeHandle node)
 resets the counter of failed responses
void setRTT (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
int joinDelay
 time interval between two join tries
int protoState
 the state in which a node currently is
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 reponses for the B bucket
int receivedLBucketLookup
 number of received lookup responses for the L bucket
int numberLBucketLookup
 maximal number of lookup reponses for the L bucket
int shiftingBits
 number of bits shifted in/out each step
int powShiftingBits
 2^{variable shiftingBits}
uint bucketSize
 maximal number of bucket entries
uint rBucketSize
 maximal number of entries in the r buckets
int parallelRequests
 number ob parallel requests
int keyLength
 length of the node and data IDs
bool refresh
 is the node restarting the bootstrap protocol or is it a new node
int pingDelay
 time intervall between bucket refreshs
int refreshTime
 time intervall after which a ping is done
uint userDist
 how many hops are added to the estimated hop count
int numPings
 actual number of received ping messages
int maxPings
 total number of ping messages
int numberRetries
 number of retries in case of timeout
int bucketCount
 number of Bucket messages
int bucketBytesSent
 length of all Bucket messages
int broosePingCount
 number of Ping messages
int broosePingBytesSent
 length of all Ping messages
int numFailedPackets
 number of packets which couldn't be routed correctly
BrooseBucketlBucket
BrooseBucketbBucket
BrooseBucket ** rBucket
cMessage * join_timer
cMessage * bucket_timer
 timer to reconstruct all buckets
NodeHandle bootstrapNode
 node handle holding the bootstrap node
BrooseHandle thisBrooseNode
 this is a BrooseHandle of the current node like thisNode

Friends

class BrooseBucket

Member Function Documentation

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.

00033 {
00034     // because of IPAddressResolver, we need to wait until interfaces
00035     // are registered, address auto-assignment takes place etc.
00036     if(stage != MIN_STAGE_OVERLAY)
00037         return;
00038 
00039     // fetch some parameters
00040     bucketSize = par("bucketSize"); // = k
00041     rBucketSize = par("rBucketSize"); // = k'
00042     parallelRequests = par("parallelRequests"); // not implemented yet
00043     joinDelay = par("joinDelay");
00044     shiftingBits = par("shiftingBits");
00045     pingDelay = par("pingDelay");
00046     userDist = par("userDist");
00047     refreshTime = par("refreshTime");
00048     numberRetries = par("numberRetries");
00049 
00050     //statistics
00051     bucketCount = 0;
00052     bucketBytesSent = 0;
00053     broosePingCount = 0;
00054     broosePingBytesSent = 0;
00055 
00056     //init local parameters
00057     chooseLookup = 0;
00058     receivedJoinResponse = 0;
00059     receivedBBucketLookup = 0;
00060     numberBBucketLookup = 0;
00061     receivedLBucketLookup = 0;
00062     numberLBucketLookup = 0;
00063     powShiftingBits = (int) pow(2.0, shiftingBits);
00064     keyLength = OverlayKey::getLength();
00065     numFailedPackets = 0;
00066     refresh = false;
00067     numPings = 0;
00068     maxPings = 0;
00069 
00070     // add some watches
00071     WATCH(receivedJoinResponse);
00072     WATCH(receivedBBucketLookup);
00073     WATCH(numberBBucketLookup);
00074     WATCH(receivedLBucketLookup);
00075     WATCH(numberLBucketLookup);
00076     WATCH(numPings);
00077     WATCH(maxPings);
00078 
00079     // get module references - these are references to the buckets
00080     // each node have in order to get a lookup done
00081     rBucket = new BrooseBucket*[powShiftingBits];
00082 
00083     for (int i = 0; i < powShiftingBits; i++) {
00084         rBucket[i] = check_and_cast<BrooseBucket*>
00085                      (parentModule()->submodule("rBucket",i));
00086     }
00087 
00088     lBucket = check_and_cast<BrooseBucket*>
00089               (parentModule()->submodule("lBucket"));
00090 
00091     bBucket = check_and_cast<BrooseBucket*>
00092               (parentModule()->submodule("bBucket"));
00093 
00094     // create join and bucket timer
00095     join_timer = new cMessage("join_timer");
00096     bucket_timer = new cMessage("bucket_timer");
00097 }

void Broose::finishOverlay (  )  [virtual]

collects statistical data in derived class

Reimplemented from BaseOverlay.

00537 {
00538     // print out statistics and delete pointers
00539 
00540     // delete timer
00541     cancelEvent(join_timer);
00542     delete join_timer;
00543 
00544     cancelEvent(bucket_timer);
00545     delete bucket_timer;
00546 
00547     // remove this node from the bootstrap list
00548     bootstrapOracle->removePeer(thisNode);
00549 
00550     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00551     if(time == 0) return;
00552 
00553     globalStatistics->addStdDev("Number of non-routable packets/s", numFailedPackets / time);
00554 
00555     globalStatistics->addStdDev("Broose: Sent BUCKET Messages/s", bucketCount / time);
00556     globalStatistics->addStdDev("Broose: Sent BUCKET Byte/s", bucketBytesSent / time);
00557 
00558     globalStatistics->addStdDev("Broose: Sent BROOSEPING Messages/s", broosePingCount / time);
00559     globalStatistics->addStdDev("Broose: Sent BROOSEPING Bytes/s", broosePingBytesSent / time);
00560 }

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.

00608 {
00609     if (key.isUnspecified())
00610         error("Broose::isSiblingFor(): key is unspecified!");
00611     
00612     if (node != thisNode)
00613         error("Broose::isSiblingsFor(): "
00614               "node != thisNode is not implemented!");
00615 
00616     if (numSiblings > getMaxNumSiblings()) {
00617         opp_error("Broose::isSiblingFor(): numSiblings too big!");
00618     }
00619     // set default number of siblings to consider
00620     if (numSiblings == -1) numSiblings = getMaxNumSiblings();
00621     
00622     if (protoState != READY) {
00623         *err = true;
00624         return false;
00625     }
00626 
00627     return bBucket->keyInRange(key);
00628 }

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.

00100 {
00101     changeState(INIT);
00102 
00103     // if the bootstrap node is unspecified we are the only node in the network
00104     // so we can skip the "normal" join protocol
00105     if (bootstrapNode.isUnspecified()) {
00106         changeState(READY);
00107     }
00108 }

void Broose::handleUDPMessage ( BaseOverlayMessage *  msg  )  [virtual]

Processes messages from underlay.

Parameters:
msg Message from UDP

Implements BaseOverlay.

00252 {
00253     error("Broose::handleUDPMessage called!");
00254 }

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.

00563 {
00564     BaseOverlayMessage* innerMsg;
00565 
00566     if (msg->getType() == OVERLAYROUTE)
00567         innerMsg = dynamic_cast<BaseOverlayMessage*>(msg->encapsulatedMsg());
00568     else
00569         innerMsg = msg;
00570 
00571     switch (innerMsg->getType()) {
00572 
00573     case RPC: {
00574             if ((dynamic_cast<BucketCall*>(innerMsg) != NULL) ||
00575                     (dynamic_cast<BucketResponse*>(innerMsg) != NULL)) {
00576                 RECORD_STATS(bucketCount++; bucketBytesSent +=
00577                                  msg->byteLength());
00578             } else if ((dynamic_cast<BroosePingCall*>(innerMsg) != NULL) ||
00579                        (dynamic_cast<BroosePingResponse*>(innerMsg) != NULL)) {
00580                 RECORD_STATS(broosePingCount++; broosePingBytesSent +=
00581                                  msg->byteLength());
00582             }
00583             break;
00584         }
00585     }
00586 }

bool Broose::handleRpc ( BaseCallMessage *  msg  )  [virtual]

Processes Remote-Procedure-Call invokation messages.


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

Returns:
true, if rpc has been handled

Reimplemented from BaseRpc.

00663 {
00664     if (protoState == BSET || protoState == READY) {
00665         // delegate messages
00666         RPC_SWITCH_START( msg )
00667         // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00668         RPC_DELEGATE(Bucket, handleBucketRequestRpc);
00669         RPC_DELEGATE(BroosePing, handleBroosePingRequestRpc);
00670         RPC_SWITCH_END( )
00671         return RPC_HANDLED;
00672     } else {
00673 //        EV << "[Broose::handleRpc() @ " << thisNode.ip
00674 //           << " (" << thisNode.key.toString(16) << ")]\n"
00675 //           << "    Received RPC call and state != READY || BSET!"
00676 //           << endl;
00677         return false;
00678     }
00679 }

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

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented from BaseOverlay.

00257 {
00258     if(msg->isName("join_timer"))
00259         handleJoinTimerExpired(msg);
00260     else if (msg->isName("bucket_timer"))
00261         handleBucketTimerExpired(msg);
00262     else
00263         error("Broose::handleTimerEvent - no other timer currently in use!");
00264 }

void Broose::updateTooltip (  ) 

updates information shown in tk-environment

00631 {
00632     if (ev.isGUI()) {
00633         std::stringstream ttString;
00634 
00635         // show our ip and key in tooltip
00636         ttString << thisNode.ip << " " << thisNode.key;
00637 
00638         parentModule()->parentModule()->displayString().
00639         setTagArg("tt", 0, ttString.str().c_str());
00640         parentModule()->displayString().
00641         setTagArg("tt", 0, ttString.str().c_str());
00642         displayString().setTagArg("tt", 0, ttString.str().c_str());
00643 
00644     }
00645 }

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

handles a expired join timer

Parameters:
msg the timer self-message
00267 {
00268     if (protoState == READY)
00269         return;
00270 
00271     if (!bootstrapNode.isUnspecified()) {
00272         // create new lookup message
00273         BucketCall* bCallArray[powShiftingBits];
00274 
00275         // do lookups for key >> shiftingBits for each prefix
00276         OverlayKey newKey = thisNode.key >> shiftingBits;
00277         for (int i = 0; i < powShiftingBits; i++) {
00278             OverlayKey add(i);
00279             add = add << (keyLength - shiftingBits);
00280             add += newKey;
00281 
00282             bCallArray[i] = new BucketCall("BBucketCall");
00283             bCallArray[i]->setBucketType(BROTHER);
00284             bCallArray[i]->setBucketIndex(i);
00285             bCallArray[i]->setProState(PINIT);
00286             bCallArray[i]->setLength(BUCKETCALL_L(bCallArray[i]));
00287 
00288             // restart join protocol if one call times out
00289             // otherwise the node might be isolated
00290             sendRpcMessage(bootstrapNode, bCallArray[i], NULL, add);
00291         }
00292     } else {
00293     // if the bootstrap node is unspecified we are the only node in the network
00294     // so we can skip the "normal" join protocol
00295         changeState(READY);
00296     }
00297 }

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

handles a expired bucket refresh timer

Parameters:
msg the bucket refresh self-message
00300 {
00301     BrooseBucket* tmpBucket = new BrooseBucket();
00302     tmpBucket->initializeBucket (0, 0, thisBrooseNode,
00303                                  (2*powShiftingBits*rBucketSize + 7*bucketSize),
00304                                  this);
00305   
00306     for (int i = 0; i < powShiftingBits; i++) {
00307         for(uint j = 0; j < rBucket[i]->getSize(); j++) {
00308             if ((simulation.simTime() - rBucket[i]->getLastSeen(
00309                      rBucket[i]->get(j))) > refreshTime
00310                 || rBucket[i]->getRTT(rBucket[i]->get(j)) == -1) {
00311                 
00312                 tmpBucket->add(BrooseHandle(rBucket[i]->get(j)));
00313             }
00314         }
00315     }
00316 
00317     for (uint i = 0; i < lBucket->getSize(); i++) {
00318         if ((simulation.simTime() - lBucket->getLastSeen(
00319                  lBucket->get(i))) > refreshTime
00320             || lBucket->getRTT(lBucket->get(i)) == -1) {
00321             
00322             tmpBucket->add(BrooseHandle(lBucket->get(i)));
00323         }
00324     }
00325 
00326     for (uint i = 0; i < bBucket->getSize(); i++) {
00327         if ((simulation.simTime() - bBucket->getLastSeen(
00328                  bBucket->get(i))) > refreshTime
00329             || bBucket->getRTT(bBucket->get(i)) == -1 ) {
00330 
00331             tmpBucket->add(BrooseHandle(bBucket->get(i)));
00332         }
00333     }
00334         
00335     maxPings = tmpBucket->getSize();
00336 
00337     if (maxPings != 0) {
00338         BroosePingCall** array = new BroosePingCall*[tmpBucket->getSize()];
00339 
00340         for (uint i = 0; i < tmpBucket->getSize(); i++) {
00341             array[i] = new BroosePingCall("PingCall");
00342             array[i]->setLength(BROOSEPINGCALL_L(array[i]));
00343 
00344             sendRpcMessage(tmpBucket->get(i), array[i]);
00345         }
00346     } else {
00347         numPings = 0;
00348         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00349     }
00350     delete tmpBucket;
00351 }

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

changes the node's state

Parameters:
state the state to which a node is changing
00112 {
00113     switch (state) {
00114     case INIT: {
00115             protoState = INIT;
00116 
00117             if (!refresh) {
00118                 // Calculate node's id by hashing its IP address
00119                 thisNode.key = OverlayKey::sha1(
00120                     const_cast<char*>(thisNode.ip.str().c_str()));
00121                 callUpdate(thisNode, true);
00122                 thisBrooseNode = BrooseHandle(thisNode);
00123                 updateTooltip();
00124             } else {
00125                 bootstrapOracle->removePeer(thisNode);
00126             }
00127 
00128             // find a new bootstrap node and enroll to the bootstrap list
00129             bootstrapNode = bootstrapOracle->getBootstrapNode();
00130 
00131             cancelEvent(join_timer);
00132             scheduleAt(simulation.simTime(), join_timer);
00133 
00134             // initialize respectively clear the buckets
00135             for (int i = 0; i < powShiftingBits; i++) {
00136                 rBucket[i]->initializeBucket(shiftingBits, i,
00137                                              thisBrooseNode, rBucketSize, this);
00138             }
00139 
00140             lBucket->initializeBucket(-shiftingBits, 0, thisBrooseNode,
00141                                       powShiftingBits*rBucketSize, this);
00142             bBucket->initializeBucket(0, 0, thisBrooseNode, 7*bucketSize,
00143                                       this, true);
00144 
00145             // if we have restarted the join protocol reset parameters
00146             refresh = false;
00147             receivedBBucketLookup = 0;
00148             receivedLBucketLookup = 0;
00149             receivedJoinResponse = 0;
00150 
00151             assert(parentModule()->parentModule());
00152             parentModule()->parentModule()->bubble("Enter INIT state.");
00153             break;
00154         }
00155 
00156     case RSET: {
00157             protoState = RSET;
00158 
00159             BrooseBucket* tmpBucket = new BrooseBucket();
00160             tmpBucket->initializeBucket(0, 0, thisNode,
00161                                         powShiftingBits*rBucketSize, this);
00162 
00163             for (int i = 0; i < powShiftingBits; i++) {
00164                 int size = rBucket[i]->getSize();
00165 
00166                 for (int j = 0; j < size; j++) {
00167                     tmpBucket->add(rBucket[i]->get(j));
00168                 }
00169             }
00170 
00171             BucketCall** bCall = new BucketCall*[tmpBucket->getSize()];
00172             for (uint i = 0; i < tmpBucket->getSize(); i++) {
00173                 bCall[i] = new BucketCall("LBucketCall");
00174                 bCall[i]->setBucketType(LEFT);
00175                 bCall[i]->setProState(PRSET);
00176                 bCall[i]->setLength(BUCKETCALL_L(bcall[i]));
00177 
00178                 sendRpcMessage(tmpBucket->get
00179                                (i), bCall[i], NULL,
00180                                OverlayKey::UNSPECIFIED_KEY,
00181                                -1, joinDelay, numberRetries);
00182             }
00183 
00184             // half of the calls must return to init a state change
00185             numberBBucketLookup = tmpBucket->getSize();
00186             numberBBucketLookup = (numberBBucketLookup == 1) ?
00187                                   numberBBucketLookup : (numberBBucketLookup/2);
00188 
00189             delete tmpBucket;
00190 
00191             assert(parentModule()->parentModule());
00192             parentModule()->parentModule()->bubble("Enter RSET state.");
00193             break;
00194         }
00195 
00196     case BSET: {
00197             protoState = BSET;
00198 
00199             // half of the calls must return to init a state change
00200             numberLBucketLookup = bBucket->getSize();
00201             numberLBucketLookup = (numberLBucketLookup == 1) ?
00202                                   numberLBucketLookup : (numberLBucketLookup/2);
00203 
00204             // send messages to all entries of the B Bucket
00205             int size2 = bBucket->getSize();
00206             BucketCall** bCall2 = new BucketCall*[size2];
00207             for (int i = 0; i < size2; i++) {
00208                 bCall2[i] = new BucketCall("LBucketCall");
00209                 bCall2[i]->setBucketType(LEFT);
00210                 bCall2[i]->setProState(PBSET);
00211                 bCall2[i]->setLength(BUCKETCALL_L(bcall2[i]));
00212 
00213                 sendRpcMessage(bBucket->get(i), bCall2[i], NULL,
00214                                OverlayKey::UNSPECIFIED_KEY,
00215                                -1, joinDelay, numberRetries);
00216             }
00217 
00218             assert(parentModule()->parentModule());
00219             parentModule()->parentModule()->bubble("Enter BSET state.");
00220             break;
00221         }
00222 
00223     case READY: {
00224             protoState = READY;
00225             bootstrapOracle->registerPeer(thisNode);
00226 
00227             //fill the bucket also with this node
00228             for (int i = 0; i < powShiftingBits; i++)
00229                 rBucket[i]->add(thisBrooseNode);
00230             lBucket->add(thisBrooseNode);
00231             bBucket->add(thisBrooseNode);
00232 
00233             // to disable the ping protocol a pingDelay or
00234             // refreshTime of zero was given
00235             if (!(pingDelay == 0 || refreshTime == 0)) {
00236                 cancelEvent(bucket_timer);
00237                 scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00238             }
00239 
00240             assert(parentModule()->parentModule());
00241             parentModule()->parentModule()->bubble("Enter READY state.");
00242 
00243             updateTooltip();
00244             break;
00245         }
00246 
00247     }
00248     setReadyIcon(protoState == READY);
00249 }

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.

00369 {
00370     NodeVector* nextHop = new NodeVector(1);
00371     BrooseFindNodeExtMessage *findNodeExt = NULL;
00372     bool err;
00373 
00374     //return the closest nodes
00375     if (isSiblingFor(thisNode, key, numSiblings, &err)) {
00376         BrooseBucket* tmpBBucket = new BrooseBucket();
00377         BrooseHandle node;
00378         node.key = key;
00379         tmpBBucket->initializeBucket(0, 0, node, bucketSize, this);
00380         int size;
00381 
00382         if (bBucket->getSize() > bucketSize)
00383             size = bucketSize;
00384         else
00385             size = bBucket->getSize();
00386 
00387         for (uint i= 0; i < bBucket->getSize();i++)
00388             tmpBBucket->add(bBucket->get(i));
00389 
00390         // todo: this has to be returned, if baselookup can deal
00391         // with the complete vector:
00392         for (int i = 0; i < size; i++)
00393             nextHop->push_back(tmpBBucket->get(i));
00394 
00395 //        nextHop->push_back(tmpBBucket->get(0));
00396 
00397         delete tmpBBucket;
00398         return nextHop;
00399     }
00400 
00401     if (msg != NULL) {
00402         if (!msg->hasObject("findNodeExt")) {
00403             findNodeExt = new BrooseFindNodeExtMessage("findNodeExt");
00404 
00405             OverlayKey routeKey = thisNode.key;
00406             // estimate distance
00407             int dist = max(rBucket[0]->longestPrefix(),
00408                            rBucket[1]->longestPrefix()) + 1 + userDist;
00409 
00410             if ((dist % shiftingBits) != 0)
00411                 dist += (shiftingBits - (dist % shiftingBits));
00412 
00413             if (dist > keyLength) {
00414                 if ((keyLength % shiftingBits) == 0) {
00415                     dist = keyLength;
00416                 } else {
00417                     dist = (keyLength - keyLength % shiftingBits);
00418                 }
00419             }
00420 
00421             if ((chooseLookup++) % 2 == 0) {
00422                 // init left shifting lookup
00423                 findNodeExt->setRightShifting(false);
00424 
00425                 int prefix = 0;
00426                 for (int i = 0; i < dist; i++) {
00427                     prefix += thisNode.key.bitAtPlace(i+1) *
00428                         (int)pow(2.0, dist - i - 1);
00429                 }
00430 
00431                 OverlayKey pre(prefix);
00432                 routeKey = key >> dist;
00433                 routeKey += (pre << key.getLength() - dist);
00434 
00435                 dist = -dist;
00436             } else {
00437                 // init right shifting lookup
00438                 findNodeExt->setRightShifting(true);
00439             }
00440 
00441             //add contact for next Hop
00442             findNodeExt->setLastNode(thisNode);
00443             findNodeExt->setRouteKey(routeKey);
00444             findNodeExt->setStep(dist);
00445             findNodeExt->setLength(BROOSEFINDNODEEXTMESSAGE_L);
00446 
00447             msg->addObject( findNodeExt );
00448         }
00449 
00450         findNodeExt = (BrooseFindNodeExtMessage*) msg->getObject("findNodeExt");
00451     }
00452 
00453 
00454     // check for messages which couldn't be routed
00455     if (findNodeExt->getStep() == 0) {
00456         if (!isSiblingFor(thisNode, key, numSiblings, &err)) {
00457             //      cout << "Message failed - destKey " << key << "@ simtime " << simulation.simTime()
00458             // << " @node " << thisNode.ip << " lastNode " << findNodeExt->getLastNode().ip << endl;
00459             numFailedPackets++;
00460         } else
00461             error("Broose::findNode - unexpected Error");
00462         return nextHop;
00463     }
00464 
00465     if (findNodeExt->getRightShifting() == false) {
00466         // Left Shifting Lookup
00467 
00468         // can't handle left shifting lookup in BSET-State
00469         if (protoState == BSET)
00470             return nextHop;
00471 
00472         // update buckets with last hop
00473         addNode(findNodeExt->getLastNode());
00474         setLastSeen(findNodeExt->getLastNode());
00475 
00476         // replace last hop contact information with
00477         // this hop contact information
00478         findNodeExt->setLastNode(thisNode);
00479 
00480 
00481         // calculate routing key
00482         findNodeExt->setRouteKey((findNodeExt->getRouteKey()) << shiftingBits);
00483         findNodeExt->setStep(findNodeExt->getStep() + shiftingBits);
00484 
00485         // On last hop exchange routeKey for destKey especially
00486         // useful when using lookupNodeIds
00487         NodeHandle nextNode;
00488 
00489         if (findNodeExt->getStep() == 0)
00490             nextNode = lBucket->getClosestNode(key);
00491         else
00492             nextNode = lBucket->getClosestNode(findNodeExt->getRouteKey());
00493 
00494         nextHop->push_back(nextNode);
00495     } else {
00496         // Right Shifting Lookup
00497 
00498         // update buckets with last hop
00499         addNode(findNodeExt->getLastNode());
00500         setLastSeen(findNodeExt->getLastNode());
00501 
00502         // replace last hop contact information with
00503         // this hop contact information
00504         findNodeExt->setLastNode(thisNode);
00505 
00506         // calculate routing key
00507         int prefix = 0;
00508         int dist = findNodeExt->getStep();
00509         OverlayKey routeKey = findNodeExt->getRouteKey() >> shiftingBits;
00510         for (int i = 0; i < shiftingBits; i++)
00511             prefix += key.bitAtPlace(dist-i) * (int) pow (2.0, i);
00512         OverlayKey pre(prefix);
00513         routeKey += (pre << (routeKey.getLength()-shiftingBits));
00514 
00515         findNodeExt->setRouteKey(routeKey);
00516         findNodeExt->setStep(dist - shiftingBits);
00517 
00518         // On last hop exchange routeKey for destKey especially
00519         // useful when using lookupNodeIds
00520         NodeHandle nextNode;
00521 
00522         if (findNodeExt->getStep() == 0)
00523             nextNode = rBucket[prefix]->getClosestNode(key);
00524         else
00525             nextNode = rBucket[prefix]->getClosestNode(routeKey);
00526 
00527         nextHop->push_back(nextNode);
00528     }
00529 
00530     if ((*nextHop)[0] == thisNode) {
00531         return (findNode(key, numRedundantNodes, numSiblings, msg));
00532     } else
00533         return nextHop;
00534 }

bool Broose::keyBelongsToNode ( const OverlayKey key  )  [protected]

decides if a specific key is managed by this node

Parameters:
key the key
Returns:
bool value, if the key is managed by this node

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.

00355 {
00356     return bucketSize;
00357 }

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.

00360 {
00361     return bucketSize;
00362 }

void Broose::displayBucketState (  )  [protected]

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

00589 {
00590     EV << "[Broose::displayBucketState() @ " << thisNode.ip
00591        << " (" << thisNode.key.toString(16) << ")]" << endl;
00592     for (int i = 0; i < powShiftingBits; i++) {
00593         EV << "    Content of rBucket[" << i << "]: ";
00594         rBucket[i]->output();
00595     }
00596     EV << "    Content of lBucket: ";
00597     lBucket->output();
00598     EV << "    Content of bBucket: ";
00599     bBucket->output();
00600     EV << endl;
00601 }

void Broose::binaryOutput ( const OverlayKey key  )  [protected]

outputs an Overlay key in the binary system

Parameters:
key the key to output
00648 {
00649     EV << "[Broose::binaryOutput() @ " << thisNode.ip;
00650     if (key.isUnspecified()) {
00651         EV << " (<unspec>)]"
00652            << endl;
00653     } else {
00654         EV << " (";
00655         for (unsigned int i = 1; i <= key.getLength(); i++) {
00656             EV << key.bitAtPlace(i);
00657         }
00658         EV << ")]" << endl;
00659     }
00660 }

void Broose::handleRpcResponse ( BaseResponseMessage *  msg,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

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

Parameters:
msg The response message.
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

00683 {
00684     RPC_SWITCH_START(msg)
00685     RPC_ON_RESPONSE( BroosePing ) {
00686         handleBroosePingResponseRpc(_BroosePingResponse, rtt);
00687         EV << "[Broose::handleRpcResponse() @ " << thisNode.ip
00688            << " (" << thisNode.key.toString(16) << ")]\n"
00689            << "    Ping RPC Response received: id=" << rpcId << "\n"
00690            << "    msg=" << *_BroosePingResponse << " rtt=" << rtt
00691            << endl;
00692         break;
00693     }
00694     RPC_ON_RESPONSE( Bucket ) {
00695         handleBucketResponseRpc(_BucketResponse);
00696         EV << "[Broose::handleRpcResponse() @ " << thisNode.ip
00697            << " (" << thisNode.key.toString(16) << ")]\n"
00698            << "    Bucket RPC Response received: id=" << rpcId << "\n"
00699            << "    msg=" << *_BucketResponse << " rtt=" << rtt
00700            << endl;
00701         break;
00702     }
00703     RPC_SWITCH_END( )
00704 }

void Broose::handleRpcTimeout ( BaseCallMessage *  msg,
const TransportAddress dest,
int  rpcId,
const OverlayKey destKey 
) [protected, virtual]

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

Parameters:
msg The original RPC message.
dest The destination node
rpcId The RPC id.
destKey the destination OverlayKey

Reimplemented from RpcListener.

00708 {
00709     RPC_SWITCH_START(msg)
00710     RPC_ON_CALL( BroosePing ) {
00711         handleBroosePingTimeout(_BroosePingCall, dest, destKey);
00712         EV << "[Broose::handleRpcTimeout() @ " << thisNode.ip
00713            << " (" << thisNode.key.toString(16) << ")]\n"
00714            << "    Ping RPC Call timed out: id=" << rpcId << "\n"
00715            << "    msg=" << *_BroosePingCall
00716            << endl;
00717         break;
00718     }
00719     RPC_ON_CALL( FindNode ) {
00720         handleFindNodeTimeout(_FindNodeCall, dest, destKey);
00721         EV << "[Broose::handleRpcTimeout() @ " << thisNode.ip
00722            << " (" << thisNode.key.toString(16) << ")]\n"
00723            << "    Find Node RPC Call timed out: id=" << rpcId << "\n"
00724            << "    msg=" << *_FindNodeCall
00725            << endl;
00726         break;
00727     }
00728     RPC_ON_CALL( Bucket ) {
00729         handleBucketTimeout(_BucketCall);
00730         EV << "[Broose::handleRpcTimeout() @ " << thisNode.ip
00731            << " (" << thisNode.key.toString(16) << ")]\n"
00732            << "    Bucket RPC Call timed out: id=" << rpcId << "\n"
00733            << "    msg=" << *_BucketCall
00734            << endl;
00735         break;
00736     }
00737     RPC_SWITCH_END( )
00738 }

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
00744 {
00745     for (int i = 0; i < powShiftingBits; i++) {
00746         if (rBucket[i]->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00747             rBucket[i]->remove
00748                 (BrooseHandle(dest, destKey));
00749         else
00750             rBucket[i]->increaseFailedResponses(BrooseHandle(dest, destKey));
00751     }
00752 
00753     if (lBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00754         lBucket->remove
00755             (BrooseHandle(dest, destKey));
00756     else
00757         lBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00758 
00759     if (bBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00760         bBucket->remove
00761             (BrooseHandle(dest, destKey));
00762     else
00763         bBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00764 }

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

handles a received Bucket request

Parameters:
msg the message to process
00766 {
00767     if (msg->getBucketType() == LEFT) {
00768         // can't handle LBucketRequest in BSET-State
00769         if (protoState == BSET) {
00770             delete msg;
00771             return;
00772         }
00773 
00774         // return L-Bucket
00775         int size = lBucket->getSize();
00776         BucketResponse* bResponse = new BucketResponse("LBucketResponse");
00777         bResponse->setBucketType(msg->getBucketType());
00778         bResponse->setProState(msg->getProState());
00779         bResponse->setNodeNum(size);
00780         bResponse->setNodesArraySize(size);
00781 
00782         for (int i = 0; i < size; i++) {
00783             bResponse->setNodes(i, lBucket->get(i));
00784         }
00785 
00786         bResponse->setLength(BUCKETRESPONSE_L(bResponse));
00787 
00788         addNode(msg->getSrcNode());
00789         setLastSeen(msg->getSrcNode());
00790 
00791         sendRpcResponse( msg, bResponse );
00792     } else if(msg->getBucketType() == BROTHER) {
00793         // return B-Bucket
00794         int size = bBucket->getSize();
00795         BucketResponse* bResponse = new BucketResponse("BBucketResponse");
00796         bResponse->setBucketType(msg->getBucketType());
00797         bResponse->setBucketIndex(msg->getBucketIndex());
00798         bResponse->setProState(msg->getProState());
00799         bResponse->setNodeNum(size);
00800         bResponse->setNodesArraySize(size);
00801 
00802         for (int i = 0; i < size; i++) {
00803             bResponse->setNodes(i, bBucket->get(i));
00804         }
00805         bResponse->setLength(BUCKETRESPONSE_L(bResponse));
00806 
00807         sendRpcResponse( msg, bResponse );
00808     } else
00809         error("Broose::handleBucketRequestRpc() - Wrong Bucket Type!");
00810 }

void Broose::handleBucketResponseRpc ( BucketResponse *  msg  )  [protected]

handles a received Bucket response

Parameters:
msg the message to process
00813 {
00814     if (msg->getBucketType() == LEFT) {
00815         switch (protoState) {
00816         case RSET:
00817             if (msg->getProState() == PRSET) {
00818                 for (int i = 0; i < msg->getNodeNum(); i++) {
00819                     bBucket->add(BrooseHandle(msg->getNodes(i)));
00820                 }
00821                 receivedBBucketLookup++;
00822 
00823                 if (receivedBBucketLookup == numberBBucketLookup)
00824                     changeState(BSET);
00825             }
00826             break;
00827         case BSET:
00828             if (msg->getProState() == PBSET) {
00829                 for (int i = 0; i < msg->getNodeNum(); i++) {
00830                     lBucket->add(BrooseHandle(msg->getNodes(i)));
00831                 }
00832                 receivedLBucketLookup++;
00833 
00834                 if(receivedLBucketLookup == numberLBucketLookup)
00835                     changeState(READY);
00836             }
00837             break;
00838         }
00839     } else if(msg->getBucketType() == BROTHER) {
00840         switch(protoState) {
00841         case INIT:
00842             if (msg->getProState() == PINIT) {
00843                 int k = msg->getBucketIndex();
00844 
00845                 for (int i = 0; i < msg->getNodeNum(); i++) {
00846                     rBucket[k]->add(msg->getNodes(i));
00847                 }
00848 
00849                 receivedJoinResponse++;
00850                 if (receivedJoinResponse == powShiftingBits)
00851                     changeState(RSET);
00852             }
00853         }
00854     } else
00855         error("Broose::handleBucketRequestRpc() - unknown error.");
00856 }

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

handles a received Bucket timeout

Parameters:
msg the message to process
00860 {
00861     if (protoState == READY)
00862         return;
00863     else {
00864         refresh = true;
00865         changeState(INIT);
00866     }
00867 }

void Broose::handleBroosePingRequestRpc ( BroosePingCall *  msg  )  [protected]

handles a received Ping request

Parameters:
msg the message to process
00871 {
00872     BroosePingResponse* pingResponse = new BroosePingResponse("PingResponse");
00873     pingResponse->setLength(BROOSEPINGRESPONSE_L(pingResponse));
00874 
00875     // add pinging node to all buckets and update lastSeen of node
00876     addNode(msg->getSrcNode());
00877     setLastSeen(msg->getSrcNode());
00878 
00879     sendRpcResponse(msg , pingResponse);
00880 }

void Broose::handleBroosePingResponseRpc ( BroosePingResponse *  msg,
simtime_t  rtt 
) [protected]

handles a received Ping response

Parameters:
msg the message to process
rtt the round trip time of the message
00884 {
00885     // if node respond reset failedResponses and add lastSeen to node
00886     setLastSeen(msg->getSrcNode());
00887     resetFailedResponses(msg->getSrcNode());
00888     setRTT(msg->getSrcNode(), rtttime);
00889 
00890     numPings++;
00891 
00892     if (numPings == maxPings) {
00893         numPings = 0;
00894         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00895     }
00896 }

void Broose::handleBroosePingTimeout ( BroosePingCall *  msg,
const TransportAddress dest,
const OverlayKey destKey 
) [protected]

handles a received Ping timeout

Parameters:
msg the message to process
dest the destination node
destKey the destination OverlayKey
00901 {
00902     for (int i = 0; i < powShiftingBits; i++) {
00903         if (rBucket[i]->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00904             rBucket[i]->remove(BrooseHandle(dest, destKey));
00905         else
00906             rBucket[i]->increaseFailedResponses(BrooseHandle(dest, destKey));
00907     }
00908 
00909     if (lBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) {
00910         lBucket->remove(BrooseHandle(dest, destKey));
00911     } else {
00912         lBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00913     }
00914 
00915     if (bBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) {
00916         bBucket->remove(BrooseHandle(dest, destKey));
00917     } else {
00918         bBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00919     }
00920 
00921     numPings++;
00922 
00923     if (numPings == maxPings) {
00924         numPings = 0;
00925         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00926     }
00927 }

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

updates the timestamp of a node in all buckets

Parameters:
node node handle which should be updated
00930 {
00931     for (int i = 0; i < powShiftingBits; i++) {
00932         rBucket[i]->setLastSeen(BrooseHandle(node), simulation.simTime());
00933     }
00934 
00935     lBucket->setLastSeen(BrooseHandle(node), simulation.simTime());
00936     bBucket->setLastSeen(BrooseHandle(node), simulation.simTime());
00937 }

void Broose::addNode ( NodeHandle  node,
int  bucket = 0 
) [protected]

adds a node to all buckets

Parameters:
node node handle which should be added
bucket reserved
00940 {
00941     if (bucket == 0) {
00942         // add node to all buckets
00943         for (int i = 0; i < powShiftingBits; i++) {
00944             rBucket[i]->add
00945             (BrooseHandle(node));
00946         }
00947 
00948         lBucket->add(BrooseHandle(node));
00949         bBucket->add(BrooseHandle(node));
00950     } else
00951         error("Broose::addNode() - not implemented");
00952 }

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

resets the counter of failed responses

Parameters:
node node handle of the responding node
00955 {
00956     for (int i = 0; i < powShiftingBits; i++) {
00957         rBucket[i]->resetFailedResponses(BrooseHandle(node));
00958     }
00959 
00960     lBucket->resetFailedResponses(BrooseHandle(node));
00961     bBucket->resetFailedResponses(BrooseHandle(node));
00962 }

void Broose::setRTT ( 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
00965 {
00966     for (int i = 0; i < powShiftingBits; i++) {
00967         rBucket[i]->setRTT(BrooseHandle(node), rtttime);
00968     }
00969 
00970     lBucket->setRTT(BrooseHandle(node), rtttime);
00971     bBucket->setRTT(BrooseHandle(node), rtttime);
00972 }


Friends And Related Function Documentation

friend class BrooseBucket [friend]


Member Data Documentation

int Broose::chooseLookup [protected]

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

int Broose::joinDelay [protected]

time interval between two join tries

int Broose::protoState [protected]

the state in which a node currently is

int Broose::receivedJoinResponse [protected]

number of received join response messages

int Broose::receivedBBucketLookup [protected]

number of received lookup responses for the B bucket

int Broose::numberBBucketLookup [protected]

maximal number of lookup reponses for the B bucket

int Broose::receivedLBucketLookup [protected]

number of received lookup responses for the L bucket

int Broose::numberLBucketLookup [protected]

maximal number of lookup reponses for the L bucket

int Broose::shiftingBits [protected]

number of bits shifted in/out each step

int Broose::powShiftingBits [protected]

2^{variable shiftingBits}

uint Broose::bucketSize [protected]

maximal number of bucket entries

uint Broose::rBucketSize [protected]

maximal number of entries in the r buckets

int Broose::parallelRequests [protected]

number ob parallel requests

int Broose::keyLength [protected]

length of the node and data IDs

bool Broose::refresh [protected]

is the node restarting the bootstrap protocol or is it a new node

int Broose::pingDelay [protected]

time intervall between bucket refreshs

int Broose::refreshTime [protected]

time intervall after which a ping is done

uint Broose::userDist [protected]

how many hops are added to the estimated hop count

int Broose::numPings [protected]

actual number of received ping messages

int Broose::maxPings [protected]

total number of ping messages

int Broose::numberRetries [protected]

number of retries in case of timeout

int Broose::bucketCount [protected]

number of Bucket messages

int Broose::bucketBytesSent [protected]

length of all Bucket messages

int Broose::broosePingCount [protected]

number of Ping messages

int Broose::broosePingBytesSent [protected]

length of all Ping messages

int Broose::numFailedPackets [protected]

number of packets which couldn't be routed correctly

BrooseBucket* Broose::lBucket [protected]

BrooseBucket * Broose::bBucket [protected]

BrooseBucket** Broose::rBucket [protected]

cMessage* Broose::join_timer [protected]

cMessage* Broose::bucket_timer [protected]

timer to reconstruct all buckets

NodeHandle Broose::bootstrapNode [protected]

node handle holding the bootstrap node

BrooseHandle Broose::thisBrooseNode [protected]

this is a BrooseHandle of the current node like thisNode


The documentation for this class was generated from the following files:
Generated on Wed Sep 26 12:13:01 2007 for ITM OverSim by  doxygen 1.5.1