#include <Broose.h>
Inheritance diagram for Broose:
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 | |
NodeVector * | findNode (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 | |
BrooseBucket * | lBucket |
BrooseBucket * | bBucket |
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 |
void Broose::addNode | ( | NodeHandle | node, | |
int | bucket = 0 | |||
) | [protected] |
adds a node to all buckets
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
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
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.
key | The lookup key. | |
contextPtr | A pointer to the BaseRouteMessage or FindNodeCall message of this lookup. |
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
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
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
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
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
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
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
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.
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
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.
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.
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
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] |
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.
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.
key | destination 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
key | the key |
00605 { 00606 return bBucket->keyInRange(destKey); 00607 }
virtual int Broose::numInitStages | ( | ) | const [inline, virtual] |
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
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
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
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
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 }
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