#include <Broose.h>
Inheritance diagram for Broose:
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 () |
| |
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 | |
NodeVector * | findNode (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 | |
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 | |
Friends | |
class | BrooseBucket |
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.
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] |
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] |
void Broose::recordOverlaySentStats | ( | BaseOverlayMessage * | msg | ) | [virtual] |
collects statistics
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
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
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
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
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.
key | The lookup key. | |
contextPtr | A pointer to the BaseRouteMessage or FindNodeCall message of this lookup. |
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
key | the key |
int Broose::getMaxNumSiblings | ( | ) | [protected, virtual] |
Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.
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().
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] |
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.
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.
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.
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
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
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
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
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
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
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
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
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
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
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 }
friend class BrooseBucket [friend] |
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