Broose Class Reference

#include <Broose.h>

Inheritance diagram for Broose:

BaseOverlay RpcListener List of all members.

Public Member Functions

virtual void receiveChangeNotification (int category, cPolymorphic *details)
virtual int numInitStages () const
 Sets init stage.
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void finishOverlay ()
 collects statisticts
virtual bool isResponsible (const OverlayKey &key)
 Query if the node is responsible for a key.
virtual void handleUDPMessage (BaseOverlayMessage *msg)
 processes messages from underlay
virtual void recordOverlaySentStats (BaseOverlayMessage *msg)
 collects statistics
void 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, BaseOverlayMessage *msg)
 Implements the find node call.
bool keyBelongsToNode (const OverlayKey &key)
 decides if a specific key is managed by this node
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 NodeHandle &dest, int rpcId)
 This method is called if an RPC timeout has been reached.
void handleFindNodeTimeout (FindNodeCall *findNode, const NodeHandle &dest)
 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 NodeHandle &dest)
 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

Member Function Documentation

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
00895 {
00896     if (bucket == 0) {
00897         // add node to all buckets
00898         for (int i = 0; i < powShiftingBits; i++) {
00899             rBucket[i]->add
00900             (BrooseHandle(node));
00901         }
00902 
00903         lBucket->add(BrooseHandle(node));
00904         bBucket->add(BrooseHandle(node));
00905     } else
00906         error("Broose::addNode() - not implemented");
00907 }

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

outputs an Overlay key in the binary system

Parameters:
the key to output
00627 {
00628     if (key.isUnspecified()) {
00629         EV << "<unspec>";
00630     } else {
00631         for (unsigned int i = 1; i <= key.getLength(); i++) {
00632             EV << key.bitAtPlace(i);
00633         }
00634     }
00635 }

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

changes the node's state

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

void Broose::displayBucketState (  )  [protected]

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

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

NodeVector * Broose::findNode ( const OverlayKey key,
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.

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

void Broose::finishOverlay (  )  [virtual]

collects statisticts

Reimplemented from BaseOverlay.

00542 {
00543     // print out statistics and delete pointers
00544 
00545     // delete timer
00546     cancelEvent(join_timer);
00547     delete join_timer;
00548 
00549     cancelEvent(bucket_timer);
00550     delete bucket_timer;
00551 
00552     recordScalar ("Number of non-routable packets", numFailedPackets);
00553 
00554     recordScalar("Broose: Sent BUCKET Messages", bucketCount);
00555     recordScalar("Broose: Sent BUCKET Byte", bucketBytesSent);
00556 
00557     recordScalar("Broose: Sent BROOSEPING Messages", broosePingCount);
00558     recordScalar("Broose: Sent BROOSEPING Bytes", broosePingBytesSent);
00559 
00560     // remove this node from the bootstrap list
00561     bootstrapOracle->removePeer(thisNode);
00562 }

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

handles a received Ping request

Parameters:
pingCall the message to process
00827 {
00828     BroosePingResponse* pingResponse = new BroosePingResponse("PingResponse");
00829     pingResponse->setLength(BROOSEPINGRESPONSE_L(pingResponse));
00830 
00831     // add pinging node to all buckets and update lastSeen of node
00832     addNode(msg->getSrcNode());
00833     setLastSeen(msg->getSrcNode());
00834 
00835     sendRpcResponse(msg , pingResponse);
00836 }

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

handles a received Ping response

Parameters:
pingResponse the message to process
00840 {
00841     // if node respond reset failedResponses and add lastSeen to node
00842     setLastSeen(msg->getSrcNode());
00843     resetFailedResponses(msg->getSrcNode());
00844     setRTT(msg->getSrcNode(), rtttime);
00845 
00846     numPings++;
00847 
00848     if (numPings == maxPings) {
00849         numPings = 0;
00850         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00851     }
00852 }

void Broose::handleBroosePingTimeout ( BroosePingCall msg,
const NodeHandle dest 
) [protected]

handles a received Ping timeout

Parameters:
pingCall the message to process
00856 {
00857     for (int i = 0; i < powShiftingBits; i++) {
00858         if (rBucket[i]->getFailedResponses(BrooseHandle(dest)) == numberRetries)
00859             rBucket[i]->remove(BrooseHandle(dest));
00860         else
00861             rBucket[i]->increaseFailedResponses(BrooseHandle(dest));
00862     }
00863 
00864     if (lBucket->getFailedResponses(BrooseHandle(dest)) == numberRetries) {
00865         lBucket->remove(BrooseHandle(dest));
00866     } else {
00867         lBucket->increaseFailedResponses(BrooseHandle(dest));
00868     }
00869 
00870     if (bBucket->getFailedResponses(BrooseHandle(dest)) == numberRetries) {
00871         bBucket->remove(BrooseHandle(dest));
00872     } else {
00873         bBucket->increaseFailedResponses(BrooseHandle(dest));
00874     }
00875 
00876     numPings++;
00877 
00878     if (numPings == maxPings) {
00879         numPings = 0;
00880         scheduleAt(simulation.simTime() + pingDelay, bucket_timer);
00881     }
00882 }

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

handles a received Bucket request

Parameters:
bucketCall the message to process
00722 {
00723     if (msg->getBucketType() == LEFT) {
00724         // can't handle LBucketRequest in BSET-State
00725         if (protoState == BSET) {
00726             delete msg;
00727             return;
00728         }
00729 
00730         // return L-Bucket
00731         int size = lBucket->getSize();
00732         BucketResponse* bResponse = new BucketResponse("LBucketResponse");
00733         bResponse->setBucketType(msg->getBucketType());
00734         bResponse->setProState(msg->getProState());
00735         bResponse->setNodeNum(size);
00736         bResponse->setNodesArraySize(size);
00737 
00738         for (int i = 0; i < size; i++) {
00739             bResponse->setNodes(i, lBucket->get(i));
00740         }
00741 
00742         bResponse->setLength(BUCKETRESPONSE_L(bResponse));
00743 
00744         addNode(msg->getSrcNode());
00745         setLastSeen(msg->getSrcNode());
00746 
00747         sendRpcResponse( msg, bResponse );
00748     } else if(msg->getBucketType() == BROTHER) {
00749         // return B-Bucket
00750         int size = bBucket->getSize();
00751         BucketResponse* bResponse = new BucketResponse("BBucketResponse");
00752         bResponse->setBucketType(msg->getBucketType());
00753         bResponse->setBucketIndex(msg->getBucketIndex());
00754         bResponse->setProState(msg->getProState());
00755         bResponse->setNodeNum(size);
00756         bResponse->setNodesArraySize(size);
00757 
00758         for (int i = 0; i < size; i++) {
00759             bResponse->setNodes(i, bBucket->get(i));
00760         }
00761         bResponse->setLength(BUCKETRESPONSE_L(bResponse));
00762 
00763         sendRpcResponse( msg, bResponse );
00764     } else
00765         error("Broose::handleBucketRequestRpc() - Wrong Bucket Type!");
00766 }

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

handles a received Bucket response

Parameters:
bucketResponse the message to process
00769 {
00770     if (msg->getBucketType() == LEFT) {
00771         switch (protoState) {
00772         case RSET:
00773             if (msg->getProState() == PRSET) {
00774                 for (int i = 0; i < msg->getNodeNum(); i++) {
00775                     bBucket->add(BrooseHandle(msg->getNodes(i)));
00776                 }
00777                 receivedBBucketLookup++;
00778 
00779                 if (receivedBBucketLookup == numberBBucketLookup)
00780                     changeState(BSET);
00781             }
00782             break;
00783         case BSET:
00784             if (msg->getProState() == PBSET) {
00785                 for (int i = 0; i < msg->getNodeNum(); i++) {
00786                     lBucket->add(BrooseHandle(msg->getNodes(i)));
00787                 }
00788                 receivedLBucketLookup++;
00789 
00790                 if(receivedLBucketLookup == numberLBucketLookup)
00791                     changeState(READY);
00792             }
00793             break;
00794         }
00795     } else if(msg->getBucketType() == BROTHER) {
00796         switch(protoState) {
00797         case INIT:
00798             if (msg->getProState() == PINIT) {
00799                 int k = msg->getBucketIndex();
00800 
00801                 for (int i = 0; i < msg->getNodeNum(); i++) {
00802                     rBucket[k]->add(msg->getNodes(i));
00803                 }
00804 
00805                 receivedJoinResponse++;
00806                 if (receivedJoinResponse == powShiftingBits)
00807                     changeState(RSET);
00808             }
00809         }
00810     } else
00811         error("Broose::handleBucketRequestRpc() - unknown error.");
00812 }

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

handles a received Bucket timeout

Parameters:
bucketCall the message to process
00816 {
00817     if (protoState == READY)
00818         return;
00819     else {
00820         refresh = true;
00821         changeState(INIT);
00822     }
00823 }

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

handles a expired bucket refresh timer

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

void Broose::handleFindNodeTimeout ( FindNodeCall findNode,
const NodeHandle dest 
) [protected]

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

Parameters:
findNode The original FindNodeCall
dest the destination node
00700 {
00701     for (int i = 0; i < powShiftingBits; i++) {
00702         if (rBucket[i]->getFailedResponses(BrooseHandle(dest)) == numberRetries)
00703             rBucket[i]->remove
00704             (BrooseHandle(dest));
00705         else
00706             rBucket[i]->increaseFailedResponses(BrooseHandle(dest));
00707     }
00708 
00709     if (lBucket->getFailedResponses(BrooseHandle(dest)) == numberRetries)
00710         lBucket->remove
00711         (BrooseHandle(dest));
00712     else
00713         lBucket->increaseFailedResponses(BrooseHandle(dest));
00714 
00715     if (bBucket->getFailedResponses(BrooseHandle(dest)) == numberRetries)
00716         bBucket->remove
00717         (BrooseHandle(dest));
00718     else
00719         bBucket->increaseFailedResponses(BrooseHandle(dest));
00720 }

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

handles a expired join timer

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

void Broose::handleRpc ( BaseCallMessage msg  )  [virtual]

Processes Remote-Procedure-Call invokation messages.

Reimplemented from BaseOverlay.

00638 {
00639     if (protoState == BSET || protoState == READY) {
00640         // delegate messages
00641         RPC_SWITCH_START( msg )
00642         // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00643         RPC_DELEGATE(Bucket, handleBucketRequestRpc);
00644         RPC_DELEGATE(BroosePing, handleBroosePingRequestRpc);
00645         RPC_SWITCH_END( )
00646     } else {
00647         delete msg;
00648         EV << "Broose::handleRpc(): Received RPC call "
00649         << "and state != READY || BSET!" << endl;
00650     }
00651 }

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.

00655 {
00656     RPC_SWITCH_START(msg)
00657     RPC_ON_RESPONSE( BroosePing ) {
00658         handleBroosePingResponseRpc(_BroosePingResponse, rtt);
00659         EV << "Broose Ping RPC Response received: id=" << rpcId
00660         << " msg=" << *_BroosePingResponse << " rtt=" << rtt << endl;
00661         break;
00662     }
00663     RPC_ON_RESPONSE( Bucket ) {
00664         handleBucketResponseRpc(_BucketResponse);
00665         EV << "Bucket RPC Response received: id=" << rpcId
00666         << " msg=" << *_BucketResponse << " rtt=" << rtt << endl;
00667         break;
00668     }
00669     RPC_SWITCH_END( )
00670 }

void Broose::handleRpcTimeout ( BaseCallMessage msg,
const NodeHandle dest,
int  rpcId 
) [protected]

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

Parameters:
msg The original RPC message.
rpcId The RPC id.
00674 {
00675     RPC_SWITCH_START(msg)
00676     RPC_ON_CALL( BroosePing ) {
00677         handleBroosePingTimeout(_BroosePingCall, dest);
00678         EV << "Broose Ping RPC Call timed out: id=" << rpcId
00679         << " msg=" << *_BroosePingCall << endl;
00680         break;
00681     }
00682     RPC_ON_CALL( FindNode ) {
00683         handleFindNodeTimeout(_FindNodeCall, dest);
00684         EV << "Find Node RPC Call timed out: id=" << rpcId
00685         << " msg=" << *_FindNodeCall << endl;
00686         break;
00687     }
00688     RPC_ON_CALL( Bucket ) {
00689         handleBucketTimeout(_BucketCall);
00690         EV << "Bucket RPC Call timed out: id=" << rpcId
00691         << " msg=" << *_BucketCall << endl;
00692         break;
00693     }
00694     RPC_SWITCH_END( )
00695 }

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

handles self-messages

Parameters:
msg the self-message

Reimplemented from BaseOverlay.

00267 {
00268     if(msg->isName("join_timer"))
00269         handleJoinTimerExpired(msg);
00270     else if (msg->isName("bucket_timer"))
00271         handleBucketTimerExpired(msg);
00272     else
00273         error("Broose::handleTimerEvent - no other timer currently in use!");
00274 }

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

processes messages from underlay

Parameters:
msg message from UDP

Implements BaseOverlay.

00262 {
00263     error("Broose::handleUDPMessage called!");
00264 }

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

Initializes derived-class-attributes.


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

Parameters:
stage the init stage

Reimplemented from BaseOverlay.

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 
00098 
00099     changeState(INIT);
00100 
00101     // if the bootstrap node is unspecified we are the only node in the network
00102     // so we can skip the "normal" join protocol
00103     if (bootstrapNode.isUnspecified()) {
00104         changeState(READY);
00105     }
00106 
00107 }

bool Broose::isResponsible ( const OverlayKey key  )  [virtual]

Query if the node is responsible for a key.

Query if the node currently is responsible for the given key. Usually this means, that the nodeId of this node is close to the key.

Parameters:
key destination key
Returns:
bool true, if the node is responsible for the key.

Reimplemented from BaseOverlay.

00363 {
00364     if (key.isUnspecified())
00365         error("Broose::isResponsible(): key is unspecified!");
00366 
00367     if (protoState != READY)
00368         return false;
00369 
00370     return (keyBelongsToNode(key));
00371 }

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
00605 {
00606     return bBucket->keyInRange(destKey);
00607 }

virtual int Broose::numInitStages (  )  const [inline, virtual]

Sets init stage.

See also:
InitStages.h

Reimplemented from BaseOverlay.

00065     {
00066         return 6;
00067     }

void Broose::receiveChangeNotification ( int  category,
cPolymorphic *  details 
) [virtual]

00251 {
00252     Enter_Method_Silent();
00253     // get new ip address
00254     thisNode.ip = IPAddressResolver().addressOf(parentModule()->
00255                                                 parentModule()).get4();
00256 
00257     changeState(INIT);
00258 }

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

collects statistics

Parameters:
msg message which should be recorded

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 }

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

resets the counter of failed responses

Parameters:
node node handle of the responding node
00910 {
00911     for (int i = 0; i < powShiftingBits; i++) {
00912         rBucket[i]->resetFailedResponses(BrooseHandle(node));
00913     }
00914 
00915     lBucket->resetFailedResponses(BrooseHandle(node));
00916     bBucket->resetFailedResponses(BrooseHandle(node));
00917 }

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

updates the timestamp of a node in all buckets

Parameters:
node node handle which should be updated
00885 {
00886     for (int i = 0; i < powShiftingBits; i++) {
00887         rBucket[i]->setLastSeen(BrooseHandle(node), simulation.simTime());
00888     }
00889 
00890     lBucket->setLastSeen(BrooseHandle(node), simulation.simTime());
00891     bBucket->setLastSeen(BrooseHandle(node), simulation.simTime());
00892 }

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
00920 {
00921     for (int i = 0; i < powShiftingBits; i++) {
00922         rBucket[i]->setRTT(BrooseHandle(node), rtttime);
00923     }
00924 
00925     lBucket->setRTT(BrooseHandle(node), rtttime);
00926     bBucket->setRTT(BrooseHandle(node), rtttime);
00927 }

void Broose::updateTooltip (  ) 

updates information shown in tk-environment

00610 {
00611     if (ev.isGUI()) {
00612         std::stringstream ttString;
00613 
00614         // show our ip and key in tooltip
00615         ttString << thisNode.ip << " " << thisNode.key;
00616 
00617         parentModule()->parentModule()->displayString().
00618         setTagArg("tt", 0, ttString.str().c_str());
00619         parentModule()->displayString().
00620         setTagArg("tt", 0, ttString.str().c_str());
00621         displayString().setTagArg("tt", 0, ttString.str().c_str());
00622 
00623     }
00624 }


Member Data Documentation

BrooseBucket * Broose::bBucket [protected]

NodeHandle Broose::bootstrapNode [protected]

node handle holding the bootstrap node

int Broose::broosePingBytesSent [protected]

length of all Ping messages

int Broose::broosePingCount [protected]

number of Ping messages

cMessage* Broose::bucket_timer [protected]

timer to reconstruct all buckets

int Broose::bucketBytesSent [protected]

length of all Bucket messages

int Broose::bucketCount [protected]

number of Bucket messages

uint Broose::bucketSize [protected]

maximal number of bucket entries

int Broose::chooseLookup [protected]

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

cMessage* Broose::join_timer [protected]

int Broose::joinDelay [protected]

time interval between two join tries

int Broose::keyLength [protected]

length of the node and data IDs

BrooseBucket* Broose::lBucket [protected]

int Broose::maxPings [protected]

total number of ping messages

int Broose::numberBBucketLookup [protected]

maximal number of lookup reponses for the B bucket

int Broose::numberLBucketLookup [protected]

maximal number of lookup reponses for the L bucket

int Broose::numberRetries [protected]

number of retries in case of timeout

int Broose::numFailedPackets [protected]

number of packets which couldn't be routed correctly

int Broose::numPings [protected]

actual number of received ping messages

int Broose::parallelRequests [protected]

number ob parallel requests

int Broose::pingDelay [protected]

time intervall between bucket refreshs

int Broose::powShiftingBits [protected]

2^{variable shiftingBits}

int Broose::protoState [protected]

the state in which a node currently is

BrooseBucket** Broose::rBucket [protected]

uint Broose::rBucketSize [protected]

maximal number of entries in the r buckets

int Broose::receivedBBucketLookup [protected]

number of received lookup responses for the B bucket

int Broose::receivedJoinResponse [protected]

number of received join response messages

int Broose::receivedLBucketLookup [protected]

number of received lookup responses for the L bucket

bool Broose::refresh [protected]

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

int Broose::refreshTime [protected]

time intervall after which a ping is done

int Broose::shiftingBits [protected]

number of bits shifted in/out each step

BrooseHandle Broose::thisBrooseNode [protected]

this is a BrooseHandle of the current node like thisNode

uint Broose::userDist [protected]

how many hops are added to the estimated hop count


The documentation for this class was generated from the following files:
Generated on Fri May 11 14:52:39 2007 for ITM OverSim by  doxygen 1.4.7