Broose Class Reference

#include <Broose.h>

Inheritance diagram for Broose:

BaseOverlay BaseRpc TopologyVis 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.

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

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.

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

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

Reimplemented from BaseOverlay.

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

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.

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

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.

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

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

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented from BaseOverlay.

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

void Broose::updateTooltip (  ) 

updates information shown in tk-environment

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

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

handles a expired join timer

Parameters:
msg the timer self-message
00266 {
00267     if (protoState == READY)
00268         return;
00269 
00270     if (!bootstrapNode.isUnspecified()) {
00271         // create new lookup message
00272         BucketCall* bCallArray[powShiftingBits];
00273 
00274         // do lookups for key >> shiftingBits for each prefix
00275         OverlayKey newKey = thisNode.key >> shiftingBits;
00276         for (int i = 0; i < powShiftingBits; i++) {
00277             OverlayKey add(i);
00278             add = add << (keyLength - shiftingBits);
00279             add += newKey;
00280 
00281             bCallArray[i] = new BucketCall("BBucketCall");
00282             bCallArray[i]->setBucketType(BROTHER);
00283             bCallArray[i]->setBucketIndex(i);
00284             bCallArray[i]->setProState(PINIT);
00285             bCallArray[i]->setLength(BUCKETCALL_L(bCallArray[i]));
00286 
00287             // restart join protocol if one call times out
00288             // otherwise the node might be isolated
00289             sendRouteRpcCall(OVERLAY_COMP, bootstrapNode, add,
00290                              bCallArray[i]);
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             sendUdpRpcCall(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             removeBootstrapNode(thisNode);
00126         }
00127 
00128         // find a new bootstrap node and enroll to the bootstrap list
00129         bootstrapNode = 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             sendUdpRpcCall(tmpBucket->get(i), bCall[i], numberRetries,
00179                            joinDelay);
00180         }
00181 
00182         // half of the calls must return to init a state change
00183         numberBBucketLookup = tmpBucket->getSize();
00184         numberBBucketLookup = (numberBBucketLookup == 1) ?
00185                               numberBBucketLookup : (numberBBucketLookup/2);
00186 
00187         delete tmpBucket;
00188 
00189         assert(parentModule()->parentModule());
00190         parentModule()->parentModule()->bubble("Enter RSET state.");
00191         break;
00192     }
00193 
00194     case BSET: {
00195         protoState = BSET;
00196 
00197         // half of the calls must return to init a state change
00198         numberLBucketLookup = bBucket->getSize();
00199         numberLBucketLookup = (numberLBucketLookup == 1) ?
00200                               numberLBucketLookup : (numberLBucketLookup/2);
00201 
00202         // send messages to all entries of the B Bucket
00203         int size2 = bBucket->getSize();
00204         BucketCall** bCall2 = new BucketCall*[size2];
00205         for (int i = 0; i < size2; i++) {
00206             bCall2[i] = new BucketCall("LBucketCall");
00207             bCall2[i]->setBucketType(LEFT);
00208             bCall2[i]->setProState(PBSET);
00209             bCall2[i]->setLength(BUCKETCALL_L(bcall2[i]));
00210 
00211             sendUdpRpcCall(bBucket->get(i), bCall2[i], numberRetries,
00212                            joinDelay);
00213         }
00214 
00215         assert(parentModule()->parentModule());
00216         parentModule()->parentModule()->bubble("Enter BSET state.");
00217         break;
00218     }
00219 
00220     case READY: {
00221         protoState = READY;
00222 //        registerBootstrapNode(thisNode);
00223 
00224         //fill the bucket also with this node
00225         for (int i = 0; i < powShiftingBits; i++) {
00226             rBucket[i]->add(thisBrooseNode);
00227         }
00228         
00229         lBucket->add(thisBrooseNode);
00230         bBucket->add(thisBrooseNode);
00231 
00232         // to disable the ping protocol a pingDelay or
00233         // refreshTime of zero was given
00234         if (!(pingDelay == 0 || refreshTime == 0)) {
00235             cancelEvent(bucket_timer);
00236             scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00237         }
00238 
00239         assert(parentModule()->parentModule());
00240         parentModule()->parentModule()->bubble("Enter READY state.");
00241 
00242         updateTooltip();
00243         break;
00244     }
00245 
00246     }
00247     setOverlayReady(protoState == READY);
00248 }

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                     prefix += thisNode.key.get(thisNode.key.getLength() - i - 1, 1) << (dist - i - 1);
00430                 }
00431 
00432                 OverlayKey pre(prefix);
00433                 routeKey = key >> dist;
00434                 routeKey += (pre << key.getLength() - dist);
00435 
00436                 dist = -dist;
00437             } else {
00438                 // init right shifting lookup
00439                 findNodeExt->setRightShifting(true);
00440             }
00441 
00442             //add contact for next Hop
00443             findNodeExt->setLastNode(thisNode);
00444             findNodeExt->setRouteKey(routeKey);
00445             findNodeExt->setStep(dist);
00446             findNodeExt->setLength(BROOSEFINDNODEEXTMESSAGE_L);
00447 
00448             msg->addObject( findNodeExt );
00449         }
00450 
00451         findNodeExt = (BrooseFindNodeExtMessage*) msg->getObject("findNodeExt");
00452     }
00453 
00454 
00455     // check for messages which couldn't be routed
00456     if (findNodeExt->getStep() == 0) {
00457         if (!isSiblingFor(thisNode, key, numSiblings, &err)) {
00458             //      cout << "Message failed - destKey " << key << "@ simtime " << simulation.simTime()
00459             // << " @node " << thisNode.ip << " lastNode " << findNodeExt->getLastNode().ip << endl;
00460             numFailedPackets++;
00461         } else
00462             error("Broose::findNode - unexpected Error");
00463         return nextHop;
00464     }
00465 
00466     if (findNodeExt->getRightShifting() == false) {
00467         // Left Shifting Lookup
00468 
00469         // can't handle left shifting lookup in BSET-State
00470         if (protoState == BSET)
00471             return nextHop;
00472 
00473         // update buckets with last hop
00474         addNode(findNodeExt->getLastNode());
00475         setLastSeen(findNodeExt->getLastNode());
00476 
00477         // replace last hop contact information with
00478         // this hop contact information
00479         findNodeExt->setLastNode(thisNode);
00480 
00481 
00482         // calculate routing key
00483         findNodeExt->setRouteKey((findNodeExt->getRouteKey()) << shiftingBits);
00484         findNodeExt->setStep(findNodeExt->getStep() + shiftingBits);
00485 
00486         // On last hop exchange routeKey for destKey especially
00487         // useful when using lookupNodeIds
00488         NodeHandle nextNode;
00489 
00490         if (findNodeExt->getStep() == 0)
00491             nextNode = lBucket->getClosestNode(key);
00492         else
00493             nextNode = lBucket->getClosestNode(findNodeExt->getRouteKey());
00494 
00495         nextHop->push_back(nextNode);
00496     } else {
00497         // Right Shifting Lookup
00498 
00499         // update buckets with last hop
00500         addNode(findNodeExt->getLastNode());
00501         setLastSeen(findNodeExt->getLastNode());
00502 
00503         // replace last hop contact information with
00504         // this hop contact information
00505         findNodeExt->setLastNode(thisNode);
00506 
00507         // calculate routing key
00508         int prefix = 0;
00509         int dist = findNodeExt->getStep();
00510         OverlayKey routeKey = findNodeExt->getRouteKey() >> shiftingBits;
00511         for (int i = 0; i < shiftingBits; i++)
00512 //             prefix += key.bitAtPlace(dist-i) * (int) pow (2.0, i);
00513             prefix += key.get(key.getLength() - dist + i, 1) << i;
00514         OverlayKey pre(prefix);
00515         routeKey += (pre << (routeKey.getLength()-shiftingBits));
00516 
00517         findNodeExt->setRouteKey(routeKey);
00518         findNodeExt->setStep(dist - shiftingBits);
00519 
00520         // On last hop exchange routeKey for destKey especially
00521         // useful when using lookupNodeIds
00522         NodeHandle nextNode;
00523 
00524         if (findNodeExt->getStep() == 0)
00525             nextNode = rBucket[prefix]->getClosestNode(key);
00526         else
00527             nextNode = rBucket[prefix]->getClosestNode(routeKey);
00528 
00529         nextHop->push_back(nextNode);
00530     }
00531 
00532     if ((*nextHop)[0] == thisNode) {
00533         return (findNode(key, numRedundantNodes, numSiblings, msg));
00534     } else
00535         return nextHop;
00536 }

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

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

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

outputs an Overlay key in the binary system

Parameters:
key the key to output
00651 {
00652     EV << "[Broose::binaryOutput() @ " << thisNode.ip;
00653     if (key.isUnspecified()) {
00654         EV << " (<unspec>)]"
00655         << endl;
00656     } else {
00657         EV << " (";
00658         for (unsigned int i = 1; i <= key.getLength(); i++) {
00659 /*            EV << key.bitAtPlace(i);*/
00660             EV << key.get(key.getLength() - i, 1);
00661         }
00662         EV << ")]" << endl;
00663     }
00664 }

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.

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

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.

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

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

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

handles a received Bucket request

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

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

handles a received Bucket response

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

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

handles a received Bucket timeout

Parameters:
msg the message to process
00864 {
00865     if (protoState == READY)
00866         return;
00867     else {
00868         refresh = true;
00869         changeState(INIT);
00870     }
00871 }

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

handles a received Ping request

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

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
00888 {
00889     // if node respond reset failedResponses and add lastSeen to node
00890     setLastSeen(msg->getSrcNode());
00891     resetFailedResponses(msg->getSrcNode());
00892     setRTT(msg->getSrcNode(), rtttime);
00893 
00894     numPings++;
00895 
00896     if (numPings == maxPings) {
00897         numPings = 0;
00898         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00899     }
00900 }

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
00905 {
00906     for (int i = 0; i < powShiftingBits; i++) {
00907         if (rBucket[i]->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00908             rBucket[i]->remove(BrooseHandle(dest, destKey));
00909         else
00910             rBucket[i]->increaseFailedResponses(BrooseHandle(dest, destKey));
00911     }
00912 
00913     if (lBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) {
00914         lBucket->remove(BrooseHandle(dest, destKey));
00915     } else {
00916         lBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00917     }
00918 
00919     if (bBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) {
00920         bBucket->remove(BrooseHandle(dest, destKey));
00921     } else {
00922         bBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00923     }
00924 
00925     numPings++;
00926 
00927     if (numPings == maxPings) {
00928         numPings = 0;
00929         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00930     }
00931 }

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

updates the timestamp of a node in all buckets

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

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
00944 {
00945     if (bucket == 0) {
00946         // add node to all buckets
00947         for (int i = 0; i < powShiftingBits; i++) {
00948             rBucket[i]->add
00949             (BrooseHandle(node));
00950         }
00951 
00952         lBucket->add(BrooseHandle(node));
00953         bBucket->add(BrooseHandle(node));
00954     } else
00955         error("Broose::addNode() - not implemented");
00956 }

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

resets the counter of failed responses

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

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
00969 {
00970     for (int i = 0; i < powShiftingBits; i++) {
00971         rBucket[i]->setRTT(BrooseHandle(node), rtttime);
00972     }
00973 
00974     lBucket->setRTT(BrooseHandle(node), rtttime);
00975     bBucket->setRTT(BrooseHandle(node), rtttime);
00976 }


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 Thu Apr 17 13:19:28 2008 for ITM OverSim by  doxygen 1.5.3