#include <Broose.h>
Inheritance diagram for Broose:
Public Member Functions | |
virtual void | initializeOverlay (int stage) |
Initializes derived-class-attributes. | |
virtual void | finishOverlay () |
collects statistical data in derived class | |
virtual bool | isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err) |
Query if a node is among the siblings for a given key. | |
virtual void | joinOverlay () |
Join the overlay with a given nodeID in thisNode.key. | |
virtual void | handleUDPMessage (BaseOverlayMessage *msg) |
Processes messages from underlay. | |
virtual void | recordOverlaySentStats (BaseOverlayMessage *msg) |
Collect overlay specific sent messages statistics. | |
virtual bool | handleRpc (BaseCallMessage *msg) |
Processes Remote-Procedure-Call invokation messages. | |
virtual void | handleTimerEvent (cMessage *msg) |
Processes "timer" self-messages. | |
void | updateTooltip () |
updates information shown in tk-environment | |
Protected Member Functions | |
void | handleJoinTimerExpired (cMessage *msg) |
handles a expired join timer | |
void | handleBucketTimerExpired (cMessage *msg) |
handles a expired bucket refresh timer | |
void | changeState (int state) |
changes the node's state | |
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::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.0, shiftingBits); 00064 keyLength = OverlayKey::getLength(); 00065 numFailedPackets = 0; 00066 refresh = false; 00067 numPings = 0; 00068 maxPings = 0; 00069 00070 // add some watches 00071 WATCH(receivedJoinResponse); 00072 WATCH(receivedBBucketLookup); 00073 WATCH(numberBBucketLookup); 00074 WATCH(receivedLBucketLookup); 00075 WATCH(numberLBucketLookup); 00076 WATCH(numPings); 00077 WATCH(maxPings); 00078 00079 // get module references - these are references to the buckets 00080 // each node have in order to get a lookup done 00081 rBucket = new BrooseBucket*[powShiftingBits]; 00082 00083 for (int i = 0; i < powShiftingBits; i++) { 00084 rBucket[i] = check_and_cast<BrooseBucket*> 00085 (parentModule()->submodule("rBucket",i)); 00086 } 00087 00088 lBucket = check_and_cast<BrooseBucket*> 00089 (parentModule()->submodule("lBucket")); 00090 00091 bBucket = check_and_cast<BrooseBucket*> 00092 (parentModule()->submodule("bBucket")); 00093 00094 // create join and bucket timer 00095 join_timer = new cMessage("join_timer"); 00096 bucket_timer = new cMessage("bucket_timer"); 00097 }
void Broose::finishOverlay | ( | ) | [virtual] |
collects statistical data in derived class
Reimplemented from BaseOverlay.
00537 { 00538 // print out statistics and delete pointers 00539 00540 // delete timer 00541 cancelEvent(join_timer); 00542 delete join_timer; 00543 00544 cancelEvent(bucket_timer); 00545 delete bucket_timer; 00546 00547 // remove this node from the bootstrap list 00548 bootstrapOracle->removePeer(thisNode); 00549 00550 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00551 if(time == 0) return; 00552 00553 globalStatistics->addStdDev("Number of non-routable packets/s", numFailedPackets / time); 00554 00555 globalStatistics->addStdDev("Broose: Sent BUCKET Messages/s", bucketCount / time); 00556 globalStatistics->addStdDev("Broose: Sent BUCKET Byte/s", bucketBytesSent / time); 00557 00558 globalStatistics->addStdDev("Broose: Sent BROOSEPING Messages/s", broosePingCount / time); 00559 globalStatistics->addStdDev("Broose: Sent BROOSEPING Bytes/s", broosePingBytesSent / time); 00560 }
bool Broose::isSiblingFor | ( | const NodeHandle & | node, | |
const OverlayKey & | key, | |||
int | numSiblings, | |||
bool * | err | |||
) | [virtual] |
Query if a node is among the siblings for a given key.
Query if a node is among the siblings for a given key. This means, that the nodeId of this node is among the closest numSiblings nodes to the key and that by a local findNode() call all other siblings to this key can be retrieved.
node | the NodeHandle | |
key | destination key | |
numSiblings | The nodes knows all numSiblings nodes close to this key | |
err | return false if the range could not be determined |
Reimplemented from BaseOverlay.
00608 { 00609 if (key.isUnspecified()) 00610 error("Broose::isSiblingFor(): key is unspecified!"); 00611 00612 if (node != thisNode) 00613 error("Broose::isSiblingsFor(): " 00614 "node != thisNode is not implemented!"); 00615 00616 if (numSiblings > getMaxNumSiblings()) { 00617 opp_error("Broose::isSiblingFor(): numSiblings too big!"); 00618 } 00619 // set default number of siblings to consider 00620 if (numSiblings == -1) numSiblings = getMaxNumSiblings(); 00621 00622 if (protoState != READY) { 00623 *err = true; 00624 return false; 00625 } 00626 00627 return bBucket->keyInRange(key); 00628 }
void Broose::joinOverlay | ( | ) | [virtual] |
Join the overlay with a given nodeID in thisNode.key.
Join the overlay with a given nodeID in thisNode.key. This method may be called by an application to join the overlay with a specific nodeID. It is also called if the node's IP address changes.
Reimplemented from BaseOverlay.
00100 { 00101 changeState(INIT); 00102 00103 // if the bootstrap node is unspecified we are the only node in the network 00104 // so we can skip the "normal" join protocol 00105 if (bootstrapNode.isUnspecified()) { 00106 changeState(READY); 00107 } 00108 }
void Broose::handleUDPMessage | ( | BaseOverlayMessage * | msg | ) | [virtual] |
void Broose::recordOverlaySentStats | ( | BaseOverlayMessage * | msg | ) | [virtual] |
Collect overlay specific sent messages statistics.
This method is called from BaseOverlay::sendMessageToUDP() for every overlay message that is sent by a node. Use this to collect statistical data for overlay protocol specific message types.
msg | The overlay message to be sent to the UDP layer |
Reimplemented from BaseOverlay.
00563 { 00564 BaseOverlayMessage* innerMsg; 00565 00566 if (msg->getType() == OVERLAYROUTE) 00567 innerMsg = dynamic_cast<BaseOverlayMessage*>(msg->encapsulatedMsg()); 00568 else 00569 innerMsg = msg; 00570 00571 switch (innerMsg->getType()) { 00572 00573 case RPC: { 00574 if ((dynamic_cast<BucketCall*>(innerMsg) != NULL) || 00575 (dynamic_cast<BucketResponse*>(innerMsg) != NULL)) { 00576 RECORD_STATS(bucketCount++; bucketBytesSent += 00577 msg->byteLength()); 00578 } else if ((dynamic_cast<BroosePingCall*>(innerMsg) != NULL) || 00579 (dynamic_cast<BroosePingResponse*>(innerMsg) != NULL)) { 00580 RECORD_STATS(broosePingCount++; broosePingBytesSent += 00581 msg->byteLength()); 00582 } 00583 break; 00584 } 00585 } 00586 }
bool Broose::handleRpc | ( | BaseCallMessage * | msg | ) | [virtual] |
Processes Remote-Procedure-Call invokation messages.
This method should be overloaded when the overlay provides RPC functionality.
Reimplemented from BaseRpc.
00663 { 00664 if (protoState == BSET || protoState == READY) { 00665 // delegate messages 00666 RPC_SWITCH_START( msg ) 00667 // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> ) 00668 RPC_DELEGATE(Bucket, handleBucketRequestRpc); 00669 RPC_DELEGATE(BroosePing, handleBroosePingRequestRpc); 00670 RPC_SWITCH_END( ) 00671 return RPC_HANDLED; 00672 } else { 00673 // EV << "[Broose::handleRpc() @ " << thisNode.ip 00674 // << " (" << thisNode.key.toString(16) << ")]\n" 00675 // << " Received RPC call and state != READY || BSET!" 00676 // << endl; 00677 return false; 00678 } 00679 }
void Broose::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
Processes "timer" self-messages.
msg | A self-message |
Reimplemented from BaseOverlay.
00257 { 00258 if(msg->isName("join_timer")) 00259 handleJoinTimerExpired(msg); 00260 else if (msg->isName("bucket_timer")) 00261 handleBucketTimerExpired(msg); 00262 else 00263 error("Broose::handleTimerEvent - no other timer currently in use!"); 00264 }
void Broose::updateTooltip | ( | ) |
updates information shown in tk-environment
00631 { 00632 if (ev.isGUI()) { 00633 std::stringstream ttString; 00634 00635 // show our ip and key in tooltip 00636 ttString << thisNode.ip << " " << thisNode.key; 00637 00638 parentModule()->parentModule()->displayString(). 00639 setTagArg("tt", 0, ttString.str().c_str()); 00640 parentModule()->displayString(). 00641 setTagArg("tt", 0, ttString.str().c_str()); 00642 displayString().setTagArg("tt", 0, ttString.str().c_str()); 00643 00644 } 00645 }
void Broose::handleJoinTimerExpired | ( | cMessage * | msg | ) | [protected] |
handles a expired join timer
msg | the timer self-message |
00267 { 00268 if (protoState == READY) 00269 return; 00270 00271 if (!bootstrapNode.isUnspecified()) { 00272 // create new lookup message 00273 BucketCall* bCallArray[powShiftingBits]; 00274 00275 // do lookups for key >> shiftingBits for each prefix 00276 OverlayKey newKey = thisNode.key >> shiftingBits; 00277 for (int i = 0; i < powShiftingBits; i++) { 00278 OverlayKey add(i); 00279 add = add << (keyLength - shiftingBits); 00280 add += newKey; 00281 00282 bCallArray[i] = new BucketCall("BBucketCall"); 00283 bCallArray[i]->setBucketType(BROTHER); 00284 bCallArray[i]->setBucketIndex(i); 00285 bCallArray[i]->setProState(PINIT); 00286 bCallArray[i]->setLength(BUCKETCALL_L(bCallArray[i])); 00287 00288 // restart join protocol if one call times out 00289 // otherwise the node might be isolated 00290 sendRpcMessage(bootstrapNode, bCallArray[i], NULL, add); 00291 } 00292 } else { 00293 // if the bootstrap node is unspecified we are the only node in the network 00294 // so we can skip the "normal" join protocol 00295 changeState(READY); 00296 } 00297 }
void Broose::handleBucketTimerExpired | ( | cMessage * | msg | ) | [protected] |
handles a expired bucket refresh timer
msg | the bucket refresh self-message |
00300 { 00301 BrooseBucket* tmpBucket = new BrooseBucket(); 00302 tmpBucket->initializeBucket (0, 0, thisBrooseNode, 00303 (2*powShiftingBits*rBucketSize + 7*bucketSize), 00304 this); 00305 00306 for (int i = 0; i < powShiftingBits; i++) { 00307 for(uint j = 0; j < rBucket[i]->getSize(); j++) { 00308 if ((simulation.simTime() - rBucket[i]->getLastSeen( 00309 rBucket[i]->get(j))) > refreshTime 00310 || rBucket[i]->getRTT(rBucket[i]->get(j)) == -1) { 00311 00312 tmpBucket->add(BrooseHandle(rBucket[i]->get(j))); 00313 } 00314 } 00315 } 00316 00317 for (uint i = 0; i < lBucket->getSize(); i++) { 00318 if ((simulation.simTime() - lBucket->getLastSeen( 00319 lBucket->get(i))) > refreshTime 00320 || lBucket->getRTT(lBucket->get(i)) == -1) { 00321 00322 tmpBucket->add(BrooseHandle(lBucket->get(i))); 00323 } 00324 } 00325 00326 for (uint i = 0; i < bBucket->getSize(); i++) { 00327 if ((simulation.simTime() - bBucket->getLastSeen( 00328 bBucket->get(i))) > refreshTime 00329 || bBucket->getRTT(bBucket->get(i)) == -1 ) { 00330 00331 tmpBucket->add(BrooseHandle(bBucket->get(i))); 00332 } 00333 } 00334 00335 maxPings = tmpBucket->getSize(); 00336 00337 if (maxPings != 0) { 00338 BroosePingCall** array = new BroosePingCall*[tmpBucket->getSize()]; 00339 00340 for (uint i = 0; i < tmpBucket->getSize(); i++) { 00341 array[i] = new BroosePingCall("PingCall"); 00342 array[i]->setLength(BROOSEPINGCALL_L(array[i])); 00343 00344 sendRpcMessage(tmpBucket->get(i), array[i]); 00345 } 00346 } else { 00347 numPings = 0; 00348 scheduleAt(simulation.simTime() + pingDelay, bucket_timer); 00349 } 00350 delete tmpBucket; 00351 }
void Broose::changeState | ( | int | state | ) | [protected] |
changes the node's state
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. If the node is a sibling for this key (isSiblingFor(key) = true), this method returns all numSiblings siblings, with the closest neighbor to the key first.
key | The lookup key. | |
numRedundantNodes | Maximum number of next hop nodes to return. | |
numSiblings | number of siblings to return | |
msg | A pointer to the BaseRouteMessage or FindNodeCall message of this lookup. |
Reimplemented from BaseOverlay.
00369 { 00370 NodeVector* nextHop = new NodeVector(1); 00371 BrooseFindNodeExtMessage *findNodeExt = NULL; 00372 bool err; 00373 00374 //return the closest nodes 00375 if (isSiblingFor(thisNode, key, numSiblings, &err)) { 00376 BrooseBucket* tmpBBucket = new BrooseBucket(); 00377 BrooseHandle node; 00378 node.key = key; 00379 tmpBBucket->initializeBucket(0, 0, node, bucketSize, this); 00380 int size; 00381 00382 if (bBucket->getSize() > bucketSize) 00383 size = bucketSize; 00384 else 00385 size = bBucket->getSize(); 00386 00387 for (uint i= 0; i < bBucket->getSize();i++) 00388 tmpBBucket->add(bBucket->get(i)); 00389 00390 // todo: this has to be returned, if baselookup can deal 00391 // with the complete vector: 00392 for (int i = 0; i < size; i++) 00393 nextHop->push_back(tmpBBucket->get(i)); 00394 00395 // nextHop->push_back(tmpBBucket->get(0)); 00396 00397 delete tmpBBucket; 00398 return nextHop; 00399 } 00400 00401 if (msg != NULL) { 00402 if (!msg->hasObject("findNodeExt")) { 00403 findNodeExt = new BrooseFindNodeExtMessage("findNodeExt"); 00404 00405 OverlayKey routeKey = thisNode.key; 00406 // estimate distance 00407 int dist = max(rBucket[0]->longestPrefix(), 00408 rBucket[1]->longestPrefix()) + 1 + userDist; 00409 00410 if ((dist % shiftingBits) != 0) 00411 dist += (shiftingBits - (dist % shiftingBits)); 00412 00413 if (dist > keyLength) { 00414 if ((keyLength % shiftingBits) == 0) { 00415 dist = keyLength; 00416 } else { 00417 dist = (keyLength - keyLength % shiftingBits); 00418 } 00419 } 00420 00421 if ((chooseLookup++) % 2 == 0) { 00422 // init left shifting lookup 00423 findNodeExt->setRightShifting(false); 00424 00425 int prefix = 0; 00426 for (int i = 0; i < dist; i++) { 00427 prefix += thisNode.key.bitAtPlace(i+1) * 00428 (int)pow(2.0, dist - i - 1); 00429 } 00430 00431 OverlayKey pre(prefix); 00432 routeKey = key >> dist; 00433 routeKey += (pre << key.getLength() - dist); 00434 00435 dist = -dist; 00436 } else { 00437 // init right shifting lookup 00438 findNodeExt->setRightShifting(true); 00439 } 00440 00441 //add contact for next Hop 00442 findNodeExt->setLastNode(thisNode); 00443 findNodeExt->setRouteKey(routeKey); 00444 findNodeExt->setStep(dist); 00445 findNodeExt->setLength(BROOSEFINDNODEEXTMESSAGE_L); 00446 00447 msg->addObject( findNodeExt ); 00448 } 00449 00450 findNodeExt = (BrooseFindNodeExtMessage*) msg->getObject("findNodeExt"); 00451 } 00452 00453 00454 // check for messages which couldn't be routed 00455 if (findNodeExt->getStep() == 0) { 00456 if (!isSiblingFor(thisNode, key, numSiblings, &err)) { 00457 // cout << "Message failed - destKey " << key << "@ simtime " << simulation.simTime() 00458 // << " @node " << thisNode.ip << " lastNode " << findNodeExt->getLastNode().ip << endl; 00459 numFailedPackets++; 00460 } else 00461 error("Broose::findNode - unexpected Error"); 00462 return nextHop; 00463 } 00464 00465 if (findNodeExt->getRightShifting() == false) { 00466 // Left Shifting Lookup 00467 00468 // can't handle left shifting lookup in BSET-State 00469 if (protoState == BSET) 00470 return nextHop; 00471 00472 // update buckets with last hop 00473 addNode(findNodeExt->getLastNode()); 00474 setLastSeen(findNodeExt->getLastNode()); 00475 00476 // replace last hop contact information with 00477 // this hop contact information 00478 findNodeExt->setLastNode(thisNode); 00479 00480 00481 // calculate routing key 00482 findNodeExt->setRouteKey((findNodeExt->getRouteKey()) << shiftingBits); 00483 findNodeExt->setStep(findNodeExt->getStep() + shiftingBits); 00484 00485 // On last hop exchange routeKey for destKey especially 00486 // useful when using lookupNodeIds 00487 NodeHandle nextNode; 00488 00489 if (findNodeExt->getStep() == 0) 00490 nextNode = lBucket->getClosestNode(key); 00491 else 00492 nextNode = lBucket->getClosestNode(findNodeExt->getRouteKey()); 00493 00494 nextHop->push_back(nextNode); 00495 } else { 00496 // Right Shifting Lookup 00497 00498 // update buckets with last hop 00499 addNode(findNodeExt->getLastNode()); 00500 setLastSeen(findNodeExt->getLastNode()); 00501 00502 // replace last hop contact information with 00503 // this hop contact information 00504 findNodeExt->setLastNode(thisNode); 00505 00506 // calculate routing key 00507 int prefix = 0; 00508 int dist = findNodeExt->getStep(); 00509 OverlayKey routeKey = findNodeExt->getRouteKey() >> shiftingBits; 00510 for (int i = 0; i < shiftingBits; i++) 00511 prefix += key.bitAtPlace(dist-i) * (int) pow (2.0, i); 00512 OverlayKey pre(prefix); 00513 routeKey += (pre << (routeKey.getLength()-shiftingBits)); 00514 00515 findNodeExt->setRouteKey(routeKey); 00516 findNodeExt->setStep(dist - shiftingBits); 00517 00518 // On last hop exchange routeKey for destKey especially 00519 // useful when using lookupNodeIds 00520 NodeHandle nextNode; 00521 00522 if (findNodeExt->getStep() == 0) 00523 nextNode = rBucket[prefix]->getClosestNode(key); 00524 else 00525 nextNode = rBucket[prefix]->getClosestNode(routeKey); 00526 00527 nextHop->push_back(nextNode); 00528 } 00529 00530 if ((*nextHop)[0] == thisNode) { 00531 return (findNode(key, numRedundantNodes, numSiblings, msg)); 00532 } else 00533 return nextHop; 00534 }
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.
00355 { 00356 return bucketSize; 00357 }
int Broose::getMaxNumRedundantNodes | ( | ) | [protected, virtual] |
Query the maximum number of redundant next hop nodes that are returned by findNode().
Reimplemented from BaseOverlay.
00360 { 00361 return bucketSize; 00362 }
void Broose::displayBucketState | ( | ) | [protected] |
debug function which output the content of the node's buckets
00589 { 00590 EV << "[Broose::displayBucketState() @ " << thisNode.ip 00591 << " (" << thisNode.key.toString(16) << ")]" << endl; 00592 for (int i = 0; i < powShiftingBits; i++) { 00593 EV << " Content of rBucket[" << i << "]: "; 00594 rBucket[i]->output(); 00595 } 00596 EV << " Content of lBucket: "; 00597 lBucket->output(); 00598 EV << " Content of bBucket: "; 00599 bBucket->output(); 00600 EV << endl; 00601 }
void Broose::binaryOutput | ( | const OverlayKey & | key | ) | [protected] |
outputs an Overlay key in the binary system
key | the key to output |
00648 { 00649 EV << "[Broose::binaryOutput() @ " << thisNode.ip; 00650 if (key.isUnspecified()) { 00651 EV << " (<unspec>)]" 00652 << endl; 00653 } else { 00654 EV << " ("; 00655 for (unsigned int i = 1; i <= key.getLength(); i++) { 00656 EV << key.bitAtPlace(i); 00657 } 00658 EV << ")]" << endl; 00659 } 00660 }
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.
00683 { 00684 RPC_SWITCH_START(msg) 00685 RPC_ON_RESPONSE( BroosePing ) { 00686 handleBroosePingResponseRpc(_BroosePingResponse, rtt); 00687 EV << "[Broose::handleRpcResponse() @ " << thisNode.ip 00688 << " (" << thisNode.key.toString(16) << ")]\n" 00689 << " Ping RPC Response received: id=" << rpcId << "\n" 00690 << " msg=" << *_BroosePingResponse << " rtt=" << rtt 00691 << endl; 00692 break; 00693 } 00694 RPC_ON_RESPONSE( Bucket ) { 00695 handleBucketResponseRpc(_BucketResponse); 00696 EV << "[Broose::handleRpcResponse() @ " << thisNode.ip 00697 << " (" << thisNode.key.toString(16) << ")]\n" 00698 << " Bucket RPC Response received: id=" << rpcId << "\n" 00699 << " msg=" << *_BucketResponse << " rtt=" << rtt 00700 << endl; 00701 break; 00702 } 00703 RPC_SWITCH_END( ) 00704 }
void Broose::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
int | rpcId, | |||
const OverlayKey & | destKey | |||
) | [protected, virtual] |
This method is called if an RPC timeout has been reached.
msg | The original RPC message. | |
dest | The destination node | |
rpcId | The RPC id. | |
destKey | the destination OverlayKey |
Reimplemented from RpcListener.
00708 { 00709 RPC_SWITCH_START(msg) 00710 RPC_ON_CALL( BroosePing ) { 00711 handleBroosePingTimeout(_BroosePingCall, dest, destKey); 00712 EV << "[Broose::handleRpcTimeout() @ " << thisNode.ip 00713 << " (" << thisNode.key.toString(16) << ")]\n" 00714 << " Ping RPC Call timed out: id=" << rpcId << "\n" 00715 << " msg=" << *_BroosePingCall 00716 << endl; 00717 break; 00718 } 00719 RPC_ON_CALL( FindNode ) { 00720 handleFindNodeTimeout(_FindNodeCall, dest, destKey); 00721 EV << "[Broose::handleRpcTimeout() @ " << thisNode.ip 00722 << " (" << thisNode.key.toString(16) << ")]\n" 00723 << " Find Node RPC Call timed out: id=" << rpcId << "\n" 00724 << " msg=" << *_FindNodeCall 00725 << endl; 00726 break; 00727 } 00728 RPC_ON_CALL( Bucket ) { 00729 handleBucketTimeout(_BucketCall); 00730 EV << "[Broose::handleRpcTimeout() @ " << thisNode.ip 00731 << " (" << thisNode.key.toString(16) << ")]\n" 00732 << " Bucket RPC Call timed out: id=" << rpcId << "\n" 00733 << " msg=" << *_BucketCall 00734 << endl; 00735 break; 00736 } 00737 RPC_SWITCH_END( ) 00738 }
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 | |
destKey | the destination OverlayKey |
00744 { 00745 for (int i = 0; i < powShiftingBits; i++) { 00746 if (rBucket[i]->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) 00747 rBucket[i]->remove 00748 (BrooseHandle(dest, destKey)); 00749 else 00750 rBucket[i]->increaseFailedResponses(BrooseHandle(dest, destKey)); 00751 } 00752 00753 if (lBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) 00754 lBucket->remove 00755 (BrooseHandle(dest, destKey)); 00756 else 00757 lBucket->increaseFailedResponses(BrooseHandle(dest, destKey)); 00758 00759 if (bBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) 00760 bBucket->remove 00761 (BrooseHandle(dest, destKey)); 00762 else 00763 bBucket->increaseFailedResponses(BrooseHandle(dest, destKey)); 00764 }
void Broose::handleBucketRequestRpc | ( | BucketCall * | msg | ) | [protected] |
handles a received Bucket request
msg | the message to process |
00766 { 00767 if (msg->getBucketType() == LEFT) { 00768 // can't handle LBucketRequest in BSET-State 00769 if (protoState == BSET) { 00770 delete msg; 00771 return; 00772 } 00773 00774 // return L-Bucket 00775 int size = lBucket->getSize(); 00776 BucketResponse* bResponse = new BucketResponse("LBucketResponse"); 00777 bResponse->setBucketType(msg->getBucketType()); 00778 bResponse->setProState(msg->getProState()); 00779 bResponse->setNodeNum(size); 00780 bResponse->setNodesArraySize(size); 00781 00782 for (int i = 0; i < size; i++) { 00783 bResponse->setNodes(i, lBucket->get(i)); 00784 } 00785 00786 bResponse->setLength(BUCKETRESPONSE_L(bResponse)); 00787 00788 addNode(msg->getSrcNode()); 00789 setLastSeen(msg->getSrcNode()); 00790 00791 sendRpcResponse( msg, bResponse ); 00792 } else if(msg->getBucketType() == BROTHER) { 00793 // return B-Bucket 00794 int size = bBucket->getSize(); 00795 BucketResponse* bResponse = new BucketResponse("BBucketResponse"); 00796 bResponse->setBucketType(msg->getBucketType()); 00797 bResponse->setBucketIndex(msg->getBucketIndex()); 00798 bResponse->setProState(msg->getProState()); 00799 bResponse->setNodeNum(size); 00800 bResponse->setNodesArraySize(size); 00801 00802 for (int i = 0; i < size; i++) { 00803 bResponse->setNodes(i, bBucket->get(i)); 00804 } 00805 bResponse->setLength(BUCKETRESPONSE_L(bResponse)); 00806 00807 sendRpcResponse( msg, bResponse ); 00808 } else 00809 error("Broose::handleBucketRequestRpc() - Wrong Bucket Type!"); 00810 }
void Broose::handleBucketResponseRpc | ( | BucketResponse * | msg | ) | [protected] |
handles a received Bucket response
msg | the message to process |
00813 { 00814 if (msg->getBucketType() == LEFT) { 00815 switch (protoState) { 00816 case RSET: 00817 if (msg->getProState() == PRSET) { 00818 for (int i = 0; i < msg->getNodeNum(); i++) { 00819 bBucket->add(BrooseHandle(msg->getNodes(i))); 00820 } 00821 receivedBBucketLookup++; 00822 00823 if (receivedBBucketLookup == numberBBucketLookup) 00824 changeState(BSET); 00825 } 00826 break; 00827 case BSET: 00828 if (msg->getProState() == PBSET) { 00829 for (int i = 0; i < msg->getNodeNum(); i++) { 00830 lBucket->add(BrooseHandle(msg->getNodes(i))); 00831 } 00832 receivedLBucketLookup++; 00833 00834 if(receivedLBucketLookup == numberLBucketLookup) 00835 changeState(READY); 00836 } 00837 break; 00838 } 00839 } else if(msg->getBucketType() == BROTHER) { 00840 switch(protoState) { 00841 case INIT: 00842 if (msg->getProState() == PINIT) { 00843 int k = msg->getBucketIndex(); 00844 00845 for (int i = 0; i < msg->getNodeNum(); i++) { 00846 rBucket[k]->add(msg->getNodes(i)); 00847 } 00848 00849 receivedJoinResponse++; 00850 if (receivedJoinResponse == powShiftingBits) 00851 changeState(RSET); 00852 } 00853 } 00854 } else 00855 error("Broose::handleBucketRequestRpc() - unknown error."); 00856 }
void Broose::handleBucketTimeout | ( | BucketCall * | msg | ) | [protected] |
handles a received Bucket timeout
msg | the message to process |
00860 { 00861 if (protoState == READY) 00862 return; 00863 else { 00864 refresh = true; 00865 changeState(INIT); 00866 } 00867 }
void Broose::handleBroosePingRequestRpc | ( | BroosePingCall * | msg | ) | [protected] |
handles a received Ping request
msg | the message to process |
00871 { 00872 BroosePingResponse* pingResponse = new BroosePingResponse("PingResponse"); 00873 pingResponse->setLength(BROOSEPINGRESPONSE_L(pingResponse)); 00874 00875 // add pinging node to all buckets and update lastSeen of node 00876 addNode(msg->getSrcNode()); 00877 setLastSeen(msg->getSrcNode()); 00878 00879 sendRpcResponse(msg , pingResponse); 00880 }
void Broose::handleBroosePingResponseRpc | ( | BroosePingResponse * | msg, | |
simtime_t | rtt | |||
) | [protected] |
handles a received Ping response
msg | the message to process | |
rtt | the round trip time of the message |
00884 { 00885 // if node respond reset failedResponses and add lastSeen to node 00886 setLastSeen(msg->getSrcNode()); 00887 resetFailedResponses(msg->getSrcNode()); 00888 setRTT(msg->getSrcNode(), rtttime); 00889 00890 numPings++; 00891 00892 if (numPings == maxPings) { 00893 numPings = 0; 00894 scheduleAt(simulation.simTime() + pingDelay, bucket_timer); 00895 } 00896 }
void Broose::handleBroosePingTimeout | ( | BroosePingCall * | msg, | |
const TransportAddress & | dest, | |||
const OverlayKey & | destKey | |||
) | [protected] |
handles a received Ping timeout
msg | the message to process | |
dest | the destination node | |
destKey | the destination OverlayKey |
00901 { 00902 for (int i = 0; i < powShiftingBits; i++) { 00903 if (rBucket[i]->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) 00904 rBucket[i]->remove(BrooseHandle(dest, destKey)); 00905 else 00906 rBucket[i]->increaseFailedResponses(BrooseHandle(dest, destKey)); 00907 } 00908 00909 if (lBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) { 00910 lBucket->remove(BrooseHandle(dest, destKey)); 00911 } else { 00912 lBucket->increaseFailedResponses(BrooseHandle(dest, destKey)); 00913 } 00914 00915 if (bBucket->getFailedResponses(BrooseHandle(dest, destKey)) == numberRetries) { 00916 bBucket->remove(BrooseHandle(dest, destKey)); 00917 } else { 00918 bBucket->increaseFailedResponses(BrooseHandle(dest, destKey)); 00919 } 00920 00921 numPings++; 00922 00923 if (numPings == maxPings) { 00924 numPings = 0; 00925 scheduleAt(simulation.simTime() + pingDelay, bucket_timer); 00926 } 00927 }
void Broose::setLastSeen | ( | NodeHandle | node | ) | [protected] |
updates the timestamp of a node in all buckets
node | node handle which should be updated |
00930 { 00931 for (int i = 0; i < powShiftingBits; i++) { 00932 rBucket[i]->setLastSeen(BrooseHandle(node), simulation.simTime()); 00933 } 00934 00935 lBucket->setLastSeen(BrooseHandle(node), simulation.simTime()); 00936 bBucket->setLastSeen(BrooseHandle(node), simulation.simTime()); 00937 }
void Broose::addNode | ( | NodeHandle | node, | |
int | bucket = 0 | |||
) | [protected] |
adds a node to all buckets
node | node handle which should be added | |
bucket | reserved |
00940 { 00941 if (bucket == 0) { 00942 // add node to all buckets 00943 for (int i = 0; i < powShiftingBits; i++) { 00944 rBucket[i]->add 00945 (BrooseHandle(node)); 00946 } 00947 00948 lBucket->add(BrooseHandle(node)); 00949 bBucket->add(BrooseHandle(node)); 00950 } else 00951 error("Broose::addNode() - not implemented"); 00952 }
void Broose::resetFailedResponses | ( | NodeHandle | node | ) | [protected] |
resets the counter of failed responses
node | node handle of the responding node |
00955 { 00956 for (int i = 0; i < powShiftingBits; i++) { 00957 rBucket[i]->resetFailedResponses(BrooseHandle(node)); 00958 } 00959 00960 lBucket->resetFailedResponses(BrooseHandle(node)); 00961 bBucket->resetFailedResponses(BrooseHandle(node)); 00962 }
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 |
00965 { 00966 for (int i = 0; i < powShiftingBits; i++) { 00967 rBucket[i]->setRTT(BrooseHandle(node), rtttime); 00968 } 00969 00970 lBucket->setRTT(BrooseHandle(node), rtttime); 00971 bBucket->setRTT(BrooseHandle(node), rtttime); 00972 }
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