Broose Class Reference

#include <Broose.h>

Inheritance diagram for Broose:

BaseOverlay BaseRpc RpcListener List of all members.

Public Member Functions

virtual void receiveChangeNotification (int category, cPolymorphic *details)
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void finishOverlay ()
 collects statisticts
virtual bool isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err)
 see BaseOverlay.cc
virtual void joinOverlay ()
 
See also:
BaseOverlay.cc

virtual void handleUDPMessage (BaseOverlayMessage *msg)
 processes messages from underlay
virtual void recordOverlaySentStats (BaseOverlayMessage *msg)
 collects statistics
virtual bool handleRpc (BaseCallMessage *msg)
 Processes Remote-Procedure-Call invokation messages.
virtual void handleTimerEvent (cMessage *msg)
 handles 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::receiveChangeNotification ( int  category,
cPolymorphic *  details 
) [virtual]

00254 {
00255     Enter_Method_Silent();
00256     // get new ip address
00257     if (category == NF_HOSTPOSITION_UPDATED) {
00258         thisNode.ip = IPAddressResolver().addressOf(parentModule()->
00259                                                     parentModule()).get4();
00260         joinOverlay();
00261     }
00262 }

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, 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 statisticts

Reimplemented from BaseOverlay.

00551 {
00552     // print out statistics and delete pointers
00553 
00554     // delete timer
00555     cancelEvent(join_timer);
00556     delete join_timer;
00557 
00558     cancelEvent(bucket_timer);
00559     delete bucket_timer;
00560 
00561     // remove this node from the bootstrap list
00562     bootstrapOracle->removePeer(thisNode);
00563 
00564     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00565     if(time == 0) return;
00566 
00567     globalStatistics->addStdDev("Number of non-routable packets/s", numFailedPackets / time);
00568 
00569     globalStatistics->addStdDev("Broose: Sent BUCKET Messages/s", bucketCount / time);
00570     globalStatistics->addStdDev("Broose: Sent BUCKET Byte/s", bucketBytesSent / time);
00571 
00572     globalStatistics->addStdDev("Broose: Sent BROOSEPING Messages/s", broosePingCount / time);
00573     globalStatistics->addStdDev("Broose: Sent BROOSEPING Bytes/s", broosePingBytesSent / time);
00574 }

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

see BaseOverlay.cc

Reimplemented from BaseOverlay.

00621 {
00622     if (key.isUnspecified())
00623         error("Broose::isSiblingFor(): key is unspecified!");
00624     
00625     if (node != thisNode)
00626         error("Broose::isSiblingsFor(): "
00627               "node != thisNode is not implemented!");
00628 
00629     if (numSiblings > getMaxNumSiblings()) {
00630         opp_error("Broose::isSiblingFor(): numSiblings too big!");
00631     }
00632     // set default number of siblings to consider
00633     if (numSiblings == -1) numSiblings = getMaxNumSiblings();
00634     
00635     if (protoState != READY) {
00636         *err = true;
00637         return false;
00638     }
00639 
00640     return bBucket->keyInRange(key);
00641 }

void Broose::joinOverlay (  )  [virtual]

See also:
BaseOverlay.cc

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.

00266 {
00267     error("Broose::handleUDPMessage called!");
00268 }

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

collects statistics

Parameters:
msg message which should be recorded

Reimplemented from BaseOverlay.

00577 {
00578     BaseOverlayMessage* innerMsg;
00579 
00580     if (msg->getType() == OVERLAYROUTE)
00581         innerMsg = dynamic_cast<BaseOverlayMessage*>(msg->encapsulatedMsg());
00582     else
00583         innerMsg = msg;
00584 
00585     switch (innerMsg->getType()) {
00586 
00587     case RPC: {
00588             if ((dynamic_cast<BucketCall*>(innerMsg) != NULL) ||
00589                     (dynamic_cast<BucketResponse*>(innerMsg) != NULL)) {
00590                 RECORD_STATS(bucketCount++; bucketBytesSent +=
00591                                  msg->byteLength());
00592             } else if ((dynamic_cast<BroosePingCall*>(innerMsg) != NULL) ||
00593                        (dynamic_cast<BroosePingResponse*>(innerMsg) != NULL)) {
00594                 RECORD_STATS(broosePingCount++; broosePingBytesSent +=
00595                                  msg->byteLength());
00596             }
00597             break;
00598         }
00599     }
00600 }

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

Processes Remote-Procedure-Call invokation messages.

Reimplemented from BaseRpc.

00672 {
00673     if (protoState == BSET || protoState == READY) {
00674         // delegate messages
00675         RPC_SWITCH_START( msg )
00676         // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00677         RPC_DELEGATE(Bucket, handleBucketRequestRpc);
00678         RPC_DELEGATE(BroosePing, handleBroosePingRequestRpc);
00679         RPC_SWITCH_END( )
00680         return RPC_HANDLED;
00681     } else {
00682         //EV << "Broose::handleRpc(): Received RPC call "
00683         //<< "and state != READY || BSET!" << endl;
00684         return false;
00685     }
00686 }

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

handles self-messages

Parameters:
msg the self-message

Reimplemented from BaseOverlay.

00271 {
00272     if(msg->isName("join_timer"))
00273         handleJoinTimerExpired(msg);
00274     else if (msg->isName("bucket_timer"))
00275         handleBucketTimerExpired(msg);
00276     else
00277         error("Broose::handleTimerEvent - no other timer currently in use!");
00278 }

void Broose::updateTooltip (  ) 

updates information shown in tk-environment

00644 {
00645     if (ev.isGUI()) {
00646         std::stringstream ttString;
00647 
00648         // show our ip and key in tooltip
00649         ttString << thisNode.ip << " " << thisNode.key;
00650 
00651         parentModule()->parentModule()->displayString().
00652         setTagArg("tt", 0, ttString.str().c_str());
00653         parentModule()->displayString().
00654         setTagArg("tt", 0, ttString.str().c_str());
00655         displayString().setTagArg("tt", 0, ttString.str().c_str());
00656 
00657     }
00658 }

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

handles a expired join timer

Parameters:
msg the timer self-message
00281 {
00282     if (protoState == READY)
00283         return;
00284 
00285     if (!bootstrapNode.isUnspecified()) {
00286         // create new lookup message
00287         BucketCall* bCallArray[powShiftingBits];
00288 
00289         // do lookups for key >> shiftingBits for each prefix
00290         OverlayKey newKey = thisNode.key >> shiftingBits;
00291         for (int i = 0; i < powShiftingBits; i++) {
00292             OverlayKey add(i);
00293             add = add << (keyLength - shiftingBits);
00294             add += newKey;
00295 
00296             bCallArray[i] = new BucketCall("BBucketCall");
00297             bCallArray[i]->setBucketType(BROTHER);
00298             bCallArray[i]->setBucketIndex(i);
00299             bCallArray[i]->setProState(PINIT);
00300             bCallArray[i]->setLength(BUCKETCALL_L(bCallArray[i]));
00301 
00302             // restart join protocol if one call times out
00303             // otherwise the node might be isolated
00304             sendRpcMessage(bootstrapNode, bCallArray[i], NULL, add);
00305         }
00306     } else {
00307     // if the bootstrap node is unspecified we are the only node in the network
00308     // so we can skip the "normal" join protocol
00309         changeState(READY);
00310     }
00311 }

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

handles a expired bucket refresh timer

Parameters:
msg the bucket refresh self-message
00314 {
00315     BrooseBucket* tmpBucket = new BrooseBucket();
00316     tmpBucket->initializeBucket (0, 0, thisBrooseNode,
00317                                  (2*powShiftingBits*rBucketSize + 7*bucketSize),
00318                                  this);
00319   
00320     for (int i = 0; i < powShiftingBits; i++) {
00321         for(uint j = 0; j < rBucket[i]->getSize(); j++) {
00322             if ((simulation.simTime() - rBucket[i]->getLastSeen(
00323                      rBucket[i]->get(j))) > refreshTime
00324                 || rBucket[i]->getRTT(rBucket[i]->get(j)) == -1) {
00325                 
00326                 tmpBucket->add(BrooseHandle(rBucket[i]->get(j)));
00327             }
00328         }
00329     }
00330 
00331     for (uint i = 0; i < lBucket->getSize(); i++) {
00332         if ((simulation.simTime() - lBucket->getLastSeen(
00333                  lBucket->get(i))) > refreshTime
00334             || lBucket->getRTT(lBucket->get(i)) == -1) {
00335             
00336             tmpBucket->add(BrooseHandle(lBucket->get(i)));
00337         }
00338     }
00339 
00340     for (uint i = 0; i < bBucket->getSize(); i++) {
00341         if ((simulation.simTime() - bBucket->getLastSeen(
00342                  bBucket->get(i))) > refreshTime
00343             || bBucket->getRTT(bBucket->get(i)) == -1 ) {
00344 
00345             tmpBucket->add(BrooseHandle(bBucket->get(i)));
00346         }
00347     }
00348         
00349     maxPings = tmpBucket->getSize();
00350 
00351     if (maxPings != 0) {
00352         BroosePingCall** array = new BroosePingCall*[tmpBucket->getSize()];
00353 
00354         for (uint i = 0; i < tmpBucket->getSize(); i++) {
00355             array[i] = new BroosePingCall("PingCall");
00356             array[i]->setLength(BROOSEPINGCALL_L(array[i]));
00357 
00358             sendRpcMessage(tmpBucket->get(i), array[i]);
00359         }
00360     } else {
00361         numPings = 0;
00362         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00363     }
00364     delete tmpBucket;
00365 }

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.

Parameters:
key The lookup key.
contextPtr A pointer to the BaseRouteMessage or FindNodeCall message of this lookup.
Returns:
NodeVector with closest nodes.

Reimplemented from BaseOverlay.

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

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.

00369 {
00370     return bucketSize;
00371 }

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.

00374 {
00375     return bucketSize;
00376 }

void Broose::displayBucketState (  )  [protected]

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

00603 {
00604     EV << "Node: " << thisNode.ip << " " << thisNode.key << endl;
00605     for (int i = 0; i < powShiftingBits; i++) {
00606         EV << "Content of rBucket[" << i << "]: ";
00607         rBucket[i]->output();
00608     }
00609     EV << "Content of lBucket: ";
00610     lBucket->output();
00611     EV << "Content of bBucket: ";
00612     bBucket->output();
00613     EV << endl;
00614 }

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

outputs an Overlay key in the binary system

Parameters:
the key to output
00661 {
00662     if (key.isUnspecified()) {
00663         EV << "<unspec>";
00664     } else {
00665         for (unsigned int i = 1; i <= key.getLength(); i++) {
00666             EV << key.bitAtPlace(i);
00667         }
00668     }
00669 }

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.

00690 {
00691     RPC_SWITCH_START(msg)
00692     RPC_ON_RESPONSE( BroosePing ) {
00693         handleBroosePingResponseRpc(_BroosePingResponse, rtt);
00694         EV << "Broose Ping RPC Response received: id=" << rpcId
00695         << " msg=" << *_BroosePingResponse << " rtt=" << rtt << endl;
00696         break;
00697     }
00698     RPC_ON_RESPONSE( Bucket ) {
00699         handleBucketResponseRpc(_BucketResponse);
00700         EV << "Bucket RPC Response received: id=" << rpcId
00701         << " msg=" << *_BucketResponse << " rtt=" << rtt << endl;
00702         break;
00703     }
00704     RPC_SWITCH_END( )
00705 }

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

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

Parameters:
msg The original RPC message.
dest The original transport address
rpcId The RPC id.
destKey The original destination key
00709 {
00710     RPC_SWITCH_START(msg)
00711     RPC_ON_CALL( BroosePing ) {
00712         handleBroosePingTimeout(_BroosePingCall, dest, destKey);
00713         EV << "Broose Ping RPC Call timed out: id=" << rpcId
00714         << " msg=" << *_BroosePingCall << endl;
00715         break;
00716     }
00717     RPC_ON_CALL( FindNode ) {
00718         handleFindNodeTimeout(_FindNodeCall, dest, destKey);
00719         EV << "Find Node RPC Call timed out: id=" << rpcId
00720         << " msg=" << *_FindNodeCall << endl;
00721         break;
00722     }
00723     RPC_ON_CALL( Bucket ) {
00724         handleBucketTimeout(_BucketCall);
00725         EV << "Bucket RPC Call timed out: id=" << rpcId
00726         << " msg=" << *_BucketCall << endl;
00727         break;
00728     }
00729     RPC_SWITCH_END( )
00730 }

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
00736 {
00737     for (int i = 0; i < powShiftingBits; i++) {
00738         if (rBucket[i]->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00739             rBucket[i]->remove
00740                 (BrooseHandle(dest, destKey));
00741         else
00742             rBucket[i]->increaseFailedResponses(BrooseHandle(dest, destKey));
00743     }
00744 
00745     if (lBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00746         lBucket->remove
00747             (BrooseHandle(dest, destKey));
00748     else
00749         lBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00750 
00751     if (bBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00752         bBucket->remove
00753             (BrooseHandle(dest, destKey));
00754     else
00755         bBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00756 }

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

handles a received Bucket request

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

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

handles a received Bucket response

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

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

handles a received Bucket timeout

Parameters:
bucketCall the message to process
00852 {
00853     if (protoState == READY)
00854         return;
00855     else {
00856         refresh = true;
00857         changeState(INIT);
00858     }
00859 }

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

handles a received Ping request

Parameters:
pingCall the message to process
00863 {
00864     BroosePingResponse* pingResponse = new BroosePingResponse("PingResponse");
00865     pingResponse->setLength(BROOSEPINGRESPONSE_L(pingResponse));
00866 
00867     // add pinging node to all buckets and update lastSeen of node
00868     addNode(msg->getSrcNode());
00869     setLastSeen(msg->getSrcNode());
00870 
00871     sendRpcResponse(msg , pingResponse);
00872 }

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

handles a received Ping response

Parameters:
pingResponse the message to process
00876 {
00877     // if node respond reset failedResponses and add lastSeen to node
00878     setLastSeen(msg->getSrcNode());
00879     resetFailedResponses(msg->getSrcNode());
00880     setRTT(msg->getSrcNode(), rtttime);
00881 
00882     numPings++;
00883 
00884     if (numPings == maxPings) {
00885         numPings = 0;
00886         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00887     }
00888 }

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

handles a received Ping timeout

Parameters:
pingCall the message to process
00893 {
00894     for (int i = 0; i < powShiftingBits; i++) {
00895         if (rBucket[i]->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries)
00896             rBucket[i]->remove(BrooseHandle(dest, destKey));
00897         else
00898             rBucket[i]->increaseFailedResponses(BrooseHandle(dest, destKey));
00899     }
00900 
00901     if (lBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) {
00902         lBucket->remove(BrooseHandle(dest, destKey));
00903     } else {
00904         lBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00905     }
00906 
00907     if (bBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) {
00908         bBucket->remove(BrooseHandle(dest, destKey));
00909     } else {
00910         bBucket->increaseFailedResponses(BrooseHandle(dest, destKey));
00911     }
00912 
00913     numPings++;
00914 
00915     if (numPings == maxPings) {
00916         numPings = 0;
00917         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00918     }
00919 }

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

updates the timestamp of a node in all buckets

Parameters:
node node handle which should be updated
00922 {
00923     for (int i = 0; i < powShiftingBits; i++) {
00924         rBucket[i]->setLastSeen(BrooseHandle(node), simulation.simTime());
00925     }
00926 
00927     lBucket->setLastSeen(BrooseHandle(node), simulation.simTime());
00928     bBucket->setLastSeen(BrooseHandle(node), simulation.simTime());
00929 }

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
00932 {
00933     if (bucket == 0) {
00934         // add node to all buckets
00935         for (int i = 0; i < powShiftingBits; i++) {
00936             rBucket[i]->add
00937             (BrooseHandle(node));
00938         }
00939 
00940         lBucket->add(BrooseHandle(node));
00941         bBucket->add(BrooseHandle(node));
00942     } else
00943         error("Broose::addNode() - not implemented");
00944 }

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

resets the counter of failed responses

Parameters:
node node handle of the responding node
00947 {
00948     for (int i = 0; i < powShiftingBits; i++) {
00949         rBucket[i]->resetFailedResponses(BrooseHandle(node));
00950     }
00951 
00952     lBucket->resetFailedResponses(BrooseHandle(node));
00953     bBucket->resetFailedResponses(BrooseHandle(node));
00954 }

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
00957 {
00958     for (int i = 0; i < powShiftingBits; i++) {
00959         rBucket[i]->setRTT(BrooseHandle(node), rtttime);
00960     }
00961 
00962     lBucket->setRTT(BrooseHandle(node), rtttime);
00963     bBucket->setRTT(BrooseHandle(node), rtttime);
00964 }


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 Tue Jul 24 16:51:18 2007 for ITM OverSim by  doxygen 1.5.1