#include <Chord.h>
Inheritance diagram for Chord:
Implementation of the Chord KBR overlay as described in "Chord: A Scalable Peer-to-Peer Lookup Protocol for Inetnet Applications" by I. Stoica et al. published in Transactions on Networking.
Public Member Functions | |
virtual | ~Chord () |
virtual void | initializeOverlay (int stage) |
Initializes derived-class-attributes. | |
virtual void | receiveChangeNotification (int category, cPolymorphic *details) |
callback-method for events at the NotificationBoard | |
virtual void | handleTimerEvent (cMessage *msg) |
handles self-messages | |
virtual void | handleUDPMessage (BaseOverlayMessage *msg) |
processes messages from underlay | |
virtual void | recordOverlaySentStats (BaseOverlayMessage *msg) |
Collect overlay specific sent messages statistics. | |
virtual void | finishOverlay () |
collects statisticts | |
virtual void | updateTooltip () |
updates information shown in tk-environment | |
Protected Member Functions | |
virtual void | changeState (int toState) |
changes node state | |
virtual void | handleJoinTimerExpired (cMessage *msg) |
handle a expired join timer | |
virtual void | handleStabilizeTimerExpired (cMessage *msg) |
handle a expired stabilize timer | |
virtual void | handleFixFingersTimerExpired (cMessage *msg) |
handle a expired fix_fingers timer | |
virtual void | handleNewSuccessorHint (ChordMessage *chordMsg) |
handle a received NEWSUCCESSORHINT message | |
virtual NodeVector * | closestPreceedingNode (const OverlayKey &key) |
looks up the finger table and returns the closest preceeding node. | |
virtual void | findFriendModules () |
Assigns the finger table and succesesor list module to our reference. | |
virtual void | initializeFriendModules () |
initializes finger table and successor list | |
virtual bool | handleRpc (BaseCallMessage *msg) |
Processes Remote-Procedure-Call invokation messages. | |
NodeVector * | findNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg) |
Implements the find node call. | |
virtual void | joinOverlay () |
| |
virtual bool | isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err) |
| |
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 | rpcFixfingers (FixfingersCall *call) |
Fixfingers Remote-Procedure-Call. | |
void | rpcJoin (JoinCall *call) |
Join Remote-Procedure-Call. | |
void | rpcNotify (NotifyCall *call) |
NOTIFY Remote-Procedure-Call. | |
void | rpcStabilize (StabilizeCall *call) |
STABILIZE Remote-Procedure-Call. | |
virtual void | handleRpcResponse (BaseResponseMessage *msg, int rpcId, simtime_t rtt) |
This method is called if an RPC response has been received. | |
virtual void | handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, int rpcId) |
This method is called if an RPC timeout has been reached. | |
virtual void | handleRpcJoinResponse (JoinResponse *joinResponse) |
virtual void | handleRpcNotifyResponse (NotifyResponse *notifyResponse) |
virtual void | handleRpcStabilizeResponse (StabilizeResponse *stabilizeResponse) |
virtual void | handleRpcFixfingersResponse (FixfingersResponse *fixfingersResponse, double rtt=-1) |
virtual void | handleRpcPingResponse (PingResponse *pingResponse, int id, double rtt) |
virtual void | predecessorIsDead () |
virtual void | successorIsDead () |
Protected Attributes | |
int | joinRetry |
int | stabilizeRetry |
// retries before neighbor considered failed | |
double | joinDelay |
double | stabilizeDelay |
stabilize interval (secs) | |
double | fixfingersDelay |
int | successorListSize |
bool | aggressiveJoinMode |
use modified (faster) JOIN protocol | |
bool | extendedFingerTable |
unsigned int | numFingerCandidates |
bool | proximityRouting |
cMessage * | join_timer |
cMessage * | stabilize_timer |
cMessage * | fixfingers_timer |
int | joinCount |
int | stabilizeCount |
int | fixfingersCount |
int | notifyCount |
int | newsuccessorhintCount |
int | joinBytesSent |
int | stabilizeBytesSent |
int | notifyBytesSent |
int | fixfingersBytesSent |
int | newsuccessorhintBytesSent |
int | state |
current node state | |
int | keyLength |
length of an overlay key in bits | |
int | missingPredecessorStabRequests |
missing StabilizeCall msgs | |
int | missingSuccessorStabResponses |
missing StabilizeResponse msgs | |
NodeHandle | predecessorNode |
predecessor of this node | |
NodeHandle | bootstrapNode |
node used to bootrap | |
ChordFingerTable * | fingerTable |
pointer to this node's finger table | |
ChordSuccessorList * | successorList |
pointer to this node's successor list | |
Friends | |
class | ChordSuccessorList |
Chord::~Chord | ( | ) | [virtual] |
00094 { 00095 // destroy self timer messages 00096 cancelEvent(join_timer); 00097 cancelEvent(stabilize_timer); 00098 cancelEvent(fixfingers_timer); 00099 00100 delete join_timer; 00101 delete stabilize_timer; 00102 delete fixfingers_timer; 00103 }
void Chord::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.
Reimplemented in Koorde.
00039 { 00040 // because of IPAddressResolver, we need to wait until interfaces 00041 // are registered, address auto-assignment takes place etc. 00042 if(stage != MIN_STAGE_OVERLAY) 00043 return; 00044 00045 // fetch some parameters 00046 useCommonAPIforward = par("useCommonAPIforward"); 00047 successorListSize = par("successorListSize"); 00048 joinRetry = par("joinRetry"); 00049 stabilizeRetry = par("stabilizeRetry"); 00050 joinDelay = par("joinDelay"); 00051 stabilizeDelay = par("stabilizeDelay"); 00052 fixfingersDelay = par("fixfingersDelay"); 00053 aggressiveJoinMode = par("aggressiveJoinMode"); 00054 extendedFingerTable = par("extendedFingerTable"); 00055 numFingerCandidates = par("numFingerCandidates"); 00056 proximityRouting = par("proximityRouting"); 00057 00058 keyLength = OverlayKey::getLength(); 00059 missingPredecessorStabRequests = 0; 00060 missingSuccessorStabResponses = 0; 00061 00062 // statistics 00063 joinCount = 0; 00064 stabilizeCount = 0; 00065 fixfingersCount = 0; 00066 notifyCount = 0; 00067 newsuccessorhintCount = 0; 00068 joinBytesSent = 0; 00069 stabilizeBytesSent = 0; 00070 notifyBytesSent = 0; 00071 fixfingersBytesSent = 0; 00072 newsuccessorhintBytesSent = 0; 00073 00074 00075 // find friend modules 00076 findFriendModules(); 00077 00078 // add some watches 00079 WATCH(predecessorNode); 00080 WATCH(thisNode); 00081 WATCH(bootstrapNode); 00082 WATCH(joinRetry); 00083 WATCH(missingPredecessorStabRequests); 00084 WATCH(missingSuccessorStabResponses); 00085 00086 // self-messages 00087 join_timer = new cMessage("join_timer"); 00088 stabilize_timer = new cMessage("stabilize_timer"); 00089 fixfingers_timer = new cMessage("fixfingers_timer"); 00090 }
void Chord::receiveChangeNotification | ( | int | category, | |
cPolymorphic * | details | |||
) | [virtual] |
callback-method for events at the NotificationBoard
category | ||
details |
00107 { 00108 Enter_Method_Silent(); 00109 if (category == NF_HOSTPOSITION_UPDATED) { 00110 // get new ip address 00111 thisNode.ip = IPAddressResolver().addressOf( 00112 parentModule()->parentModule()).get4(); 00113 00114 joinOverlay(); 00115 } 00116 }
void Chord::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
handles self-messages
msg | the self-message |
Reimplemented from BaseOverlay.
Reimplemented in Koorde.
00224 { 00225 // catch JOIN timer 00226 if (msg->isName("join_timer")) { 00227 handleJoinTimerExpired(msg); 00228 } 00229 // catch STABILIZE timer 00230 else if (msg->isName("stabilize_timer")) { 00231 handleStabilizeTimerExpired(msg); 00232 } 00233 // catch FIX_FINGERS timer 00234 else if (msg->isName("fixfingers_timer")) { 00235 handleFixFingersTimerExpired(msg); 00236 } 00237 // unknown self message 00238 else { 00239 error("Chord::handleTimerEvent(): received self message of " 00240 "unknown type!"); 00241 } 00242 }
void Chord::handleUDPMessage | ( | BaseOverlayMessage * | msg | ) | [virtual] |
processes messages from underlay
msg | message from UDP |
Implements BaseOverlay.
Reimplemented in Koorde.
00246 { 00247 ChordMessage* chordMsg = check_and_cast<ChordMessage*>(msg); 00248 switch(chordMsg->getCommand()) { 00249 case NEWSUCCESSORHINT: 00250 handleNewSuccessorHint(chordMsg); 00251 break; 00252 default: 00253 error("handleUDPMessage(): Unknown message type!"); 00254 break; 00255 } 00256 00257 delete chordMsg; 00258 }
void Chord::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.
Reimplemented in Koorde.
00603 { 00604 BaseOverlayMessage* innerMsg; 00605 00606 if (msg->getType() == OVERLAYROUTE) 00607 innerMsg = dynamic_cast<BaseOverlayMessage*>(msg->encapsulatedMsg()); 00608 else 00609 innerMsg = msg; 00610 00611 switch (innerMsg->getType()) { 00612 00613 case OVERLAYSIGNALING: { 00614 ChordMessage* chordMsg = dynamic_cast<ChordMessage*>(innerMsg); 00615 switch(chordMsg->getCommand()) { 00616 case NEWSUCCESSORHINT: 00617 RECORD_STATS(newsuccessorhintCount++; newsuccessorhintBytesSent += 00618 msg->byteLength()); 00619 break; 00620 } 00621 break; 00622 } 00623 00624 case RPC: { 00625 if ((dynamic_cast<StabilizeCall*>(innerMsg) != NULL) || 00626 (dynamic_cast<StabilizeResponse*>(innerMsg) != NULL)) { 00627 RECORD_STATS(stabilizeCount++; stabilizeBytesSent += 00628 msg->byteLength()); 00629 } else if ((dynamic_cast<NotifyCall*>(innerMsg) != NULL) || 00630 (dynamic_cast<NotifyResponse*>(innerMsg) != NULL)) { 00631 RECORD_STATS(notifyCount++; notifyBytesSent += 00632 msg->byteLength()); 00633 } else if ((dynamic_cast<FixfingersCall*>(innerMsg) != NULL) || 00634 (dynamic_cast<FixfingersResponse*>(innerMsg) != NULL)) { 00635 RECORD_STATS(fixfingersCount++; fixfingersBytesSent += 00636 msg->byteLength()); 00637 } else if ((dynamic_cast<JoinCall*>(innerMsg) != NULL) || 00638 (dynamic_cast<JoinResponse*>(innerMsg) != NULL)) { 00639 RECORD_STATS(joinCount++; joinBytesSent += msg->byteLength()); 00640 } 00641 break; 00642 } 00643 } 00644 }
void Chord::finishOverlay | ( | ) | [virtual] |
collects statisticts
Reimplemented from BaseOverlay.
Reimplemented in Koorde.
00648 { 00649 // remove this node from the bootstrap list 00650 bootstrapOracle->removePeer(thisNode); 00651 00652 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00653 if(time == 0) return; 00654 00655 globalStatistics->addStdDev("Chord: Sent JOIN Messages/s", joinCount / time); 00656 globalStatistics->addStdDev("Chord: Sent NEWSUCCESSORHINT Messages/s", 00657 newsuccessorhintCount / time); 00658 globalStatistics->addStdDev("Chord: Sent STABILIZE Messages/s", stabilizeCount / time); 00659 globalStatistics->addStdDev("Chord: Sent NOTIFY Messages/s", notifyCount / time); 00660 globalStatistics->addStdDev("Chord: Sent FIX_FINGERS Messages/s", fixfingersCount / time); 00661 globalStatistics->addStdDev("Chord: Sent JOIN Bytes/s", joinBytesSent / time); 00662 globalStatistics->addStdDev("Chord: Sent NEWSUCCESSORHINT Bytes/s", 00663 newsuccessorhintBytesSent / time); 00664 globalStatistics->addStdDev("Chord: Sent STABILIZE Bytes/s", stabilizeBytesSent / time); 00665 globalStatistics->addStdDev("Chord: Sent NOTIFY Bytes/s", notifyBytesSent / time); 00666 globalStatistics->addStdDev("Chord: Sent FIX_FINGERS Bytes/s", fixfingersBytesSent / time); 00667 }
void Chord::updateTooltip | ( | ) | [virtual] |
updates information shown in tk-environment
Reimplemented in Koorde.
01097 { 01098 if (ev.isGUI()) { 01099 std::stringstream ttString; 01100 01101 // show our predecessor and successor in tooltip 01102 ttString << predecessorNode << endl << thisNode << endl 01103 << successorList->getSuccessor(); 01104 01105 parentModule()->parentModule()->displayString(). 01106 setTagArg("tt", 0, ttString.str().c_str()); 01107 parentModule()->displayString(). 01108 setTagArg("tt", 0, ttString.str().c_str()); 01109 displayString().setTagArg("tt", 0, ttString.str().c_str()); 01110 01111 // draw an arrow to our current successor 01112 showOverlayNeighborArrow(successorList->getSuccessor(), true, 01113 "m=m,50,0,50,0;o=red,1"); 01114 showOverlayNeighborArrow(predecessorNode, false, 01115 "m=m,50,100,50,100;o=green,1"); 01116 } 01117 }
void Chord::changeState | ( | int | toState | ) | [protected, virtual] |
changes node state
toState | state to change to |
Reimplemented in Koorde.
00125 { 00126 // 00127 // Defines tasks to be executed when a state change occurs. 00128 // 00129 00130 switch (toState) { 00131 case INIT: 00132 state = INIT; 00133 00134 // remove current node handle from the bootstrap list 00135 if(!thisNode.key.isUnspecified()) { 00136 bootstrapOracle->removePeer(thisNode); 00137 } 00138 00139 // Calculate node's id by hashing its IP address 00140 // thisNode.key = OverlayKey::sha1(const_cast<char*>( 00141 // thisNode.ip.str().c_str())); 00142 // better use random numbers (our ip address might not be random) 00143 // keep old id if INIT gets called twice 00144 if (thisNode.key.isUnspecified()) { 00145 thisNode.key = OverlayKey::random(); 00146 callUpdate(thisNode, true); 00147 } 00148 00149 00150 // initialize predecessor pointer 00151 predecessorNode = NodeHandle::UNSPECIFIED_NODE; 00152 00153 // initialize finger table and successor list 00154 initializeFriendModules(); 00155 00156 updateTooltip(); 00157 00158 // debug message 00159 if (debugOutput) { 00160 EV << "CHORD: Node " << thisNode.ip 00161 << " entered INIT stage." << endl; 00162 } 00163 // FIXME: bubble() sometimes doesn't work 00164 parentModule()->parentModule()->bubble("Enter INIT state."); 00165 break; 00166 00167 case BOOTSTRAP: 00168 state = BOOTSTRAP; 00169 00170 // initiate bootstrap process 00171 cancelEvent(join_timer); 00172 // workaround: prevent notificationBoard from taking 00173 // ownership of join_timer message 00174 take(join_timer); 00175 scheduleAt(simulation.simTime(), join_timer); 00176 00177 // debug message 00178 if (debugOutput) { 00179 EV << "CHORD: Node " << thisNode.ip 00180 << " entered BOOTSTRAP stage." << endl; 00181 } 00182 parentModule()->parentModule()->bubble("Enter BOOTSTRAP state."); 00183 00184 // find a new bootstrap node and enroll to the bootstrap list 00185 bootstrapNode = bootstrapOracle->getBootstrapNode(); 00186 00187 // is this the first node? 00188 if (bootstrapNode.isUnspecified()) { 00189 // create new cord ring 00190 bootstrapNode = thisNode; 00191 changeState(READY); 00192 updateTooltip(); 00193 } 00194 break; 00195 00196 case READY: 00197 state = READY; 00198 00199 bootstrapOracle->registerPeer(thisNode); 00200 00201 // initiate stabilization protocol 00202 cancelEvent(stabilize_timer); 00203 scheduleAt(simulation.simTime() + stabilizeDelay, stabilize_timer); 00204 00205 // initiate finger repair protocol 00206 cancelEvent(fixfingers_timer); 00207 scheduleAt(simulation.simTime() + fixfingersDelay, 00208 fixfingers_timer); 00209 00210 // debug message 00211 if (debugOutput) { 00212 EV << "CHORD: Node " << thisNode.ip << " entered READY stage." 00213 << endl; 00214 } 00215 parentModule()->parentModule()->bubble("Enter READY state."); 00216 break; 00217 } 00218 00219 setReadyIcon(state == READY); 00220 }
void Chord::handleJoinTimerExpired | ( | cMessage * | msg | ) | [protected, virtual] |
handle a expired join timer
msg | the timer self-message |
00672 { 00673 // only process timer, if node is not bootstrapped yet 00674 if (state == READY) 00675 return; 00676 00677 // enter state BOOTSTRAP 00678 if (state != BOOTSTRAP) 00679 changeState(BOOTSTRAP); 00680 00681 // change bootstrap node from time to time 00682 joinRetry--; 00683 if (joinRetry == 0) { 00684 joinRetry = par("joinRetry"); 00685 changeState(BOOTSTRAP); 00686 return; 00687 } 00688 00689 // call JOIN RPC 00690 JoinCall* call = new JoinCall("JoinCall"); 00691 call->setLength(JOINCALL_L(call)); 00692 00693 sendRpcMessage(bootstrapNode, call, NULL, thisNode.key, -1, joinDelay); 00694 00695 // schedule next bootstrap process in the case this one fails 00696 cancelEvent(join_timer); 00697 scheduleAt(simulation.simTime() + joinDelay, msg); 00698 }
void Chord::handleStabilizeTimerExpired | ( | cMessage * | msg | ) | [protected, virtual] |
handle a expired stabilize timer
msg | the timer self-message |
00702 { 00703 if (state != READY) 00704 return; 00705 00706 if (missingPredecessorStabRequests >= stabilizeRetry) { 00707 // predecessor node seems to be dead 00708 // remove it from the predecessor / successor lists 00709 successorList->removeSuccessor(predecessorNode); 00710 predecessorIsDead(); 00711 00712 callUpdate(predecessorNode, false); 00713 predecessorNode = NodeHandle::UNSPECIFIED_NODE; 00714 00715 missingPredecessorStabRequests = 0; 00716 updateTooltip(); 00717 } 00718 00719 if (missingSuccessorStabResponses >= stabilizeRetry) { 00720 // successor node seems to be dead 00721 // remove it from the predecessor / successor list 00722 successorIsDead(); 00723 NodeHandle successor = successorList->popSuccessor(); 00724 00725 // if we had a ring consisting of 2 nodes and our successor seems 00726 // to be dead. Remove also predecessor because the successor 00727 // and predecessor are the same node 00728 if ((!predecessorNode.isUnspecified()) && 00729 predecessorNode == successor) { 00730 predecessorIsDead(); 00731 callUpdate(predecessorNode, false); 00732 predecessorNode = NodeHandle::UNSPECIFIED_NODE; 00733 } 00734 00735 missingSuccessorStabResponses = 0; 00736 updateTooltip(); 00737 00738 if (successorList->isEmpty()) { 00739 changeState(INIT); 00740 changeState(BOOTSTRAP); 00741 return; 00742 } 00743 } 00744 00745 if (!successorList->isEmpty()) { 00746 // call STABILIZE RPC 00747 StabilizeCall* call = new StabilizeCall("StabilizeCall"); 00748 call->setLength(STABILIZECALL_L(call)); 00749 00750 sendRpcMessage(successorList->getSuccessor(), call); 00751 00752 missingPredecessorStabRequests++; 00753 missingSuccessorStabResponses++; 00754 } 00755 00756 // schedule next stabilization process 00757 cancelEvent(stabilize_timer); 00758 scheduleAt(simulation.simTime() + stabilizeDelay, msg); 00759 }
void Chord::handleFixFingersTimerExpired | ( | cMessage * | msg | ) | [protected, virtual] |
handle a expired fix_fingers timer
msg | the timer self-message |
Reimplemented in Koorde.
00763 { 00764 if ((state != READY) || successorList->isEmpty()) 00765 return; 00766 00767 for (uint nextFinger = 0; nextFinger < thisNode.key.getLength(); 00768 nextFinger++) { 00769 // calculate "n + 2^(i - 1)" 00770 OverlayKey offset = OverlayKey::pow2(nextFinger); 00771 OverlayKey lookupKey = thisNode.key + offset; 00772 00773 // send message only for non-trivial fingers 00774 if (offset > successorList->getSuccessor().key - thisNode.key) { 00775 // call FIXFINGER RPC 00776 FixfingersCall* call = new FixfingersCall("FixfingersCall"); 00777 call->setFinger(nextFinger); 00778 call->setLength(FIXFINGERSCALL_L(call)); 00779 00780 sendRpcMessage(NodeHandle::UNSPECIFIED_NODE, call, NULL, 00781 lookupKey, -1, fixfingersDelay); 00782 00783 } else { 00784 // let trivial fingers point to the successor node 00785 fingerTable->setFinger(nextFinger, successorList->getSuccessor()); 00786 } 00787 } 00788 00789 // schedule next finger repair process 00790 cancelEvent(fixfingers_timer); 00791 scheduleAt(simulation.simTime() + fixfingersDelay, msg); 00792 }
void Chord::handleNewSuccessorHint | ( | ChordMessage * | chordMsg | ) | [protected, virtual] |
handle a received NEWSUCCESSORHINT message
chordMsg | the message to process |
00796 { 00797 NewSuccessorHintMessage* newSuccessorHintMsg = 00798 check_and_cast<NewSuccessorHintMessage*>(chordMsg); 00799 00800 // fetch the successor's predecessor 00801 NodeHandle predecessor = newSuccessorHintMsg->getPreNode(); 00802 00803 // is the successor's predecessor a new successor for this node? 00804 if (predecessor.key.isBetween(thisNode.key, 00805 successorList->getSuccessor().key) 00806 || (thisNode.key == successorList->getSuccessor().key)) { 00807 // add the successor's predecessor to the successor list 00808 successorList->addSuccessor(predecessor); 00809 updateTooltip(); 00810 } 00811 }
NodeVector * Chord::closestPreceedingNode | ( | const OverlayKey & | key | ) | [protected, virtual] |
looks up the finger table and returns the closest preceeding node.
key | key to find the closest preceeding node for |
00510 { 00511 NodeHandle tempHandle = NodeHandle::UNSPECIFIED_NODE; 00512 00513 // find the closest prceeding node in the successor list 00514 for (int j = successorList->getSize() - 1; j >= 0; j--) { 00515 if(successorList->getSuccessor(j).key.isBetweenR(thisNode.key, key)) { 00516 tempHandle = successorList->getSuccessor(j); 00517 break; 00518 } 00519 } 00520 00521 if(tempHandle.isUnspecified()) { 00522 std::stringstream temp; 00523 temp << "Error in Chord::closestPreceedingNode()!\n" << thisNode.key << "\n" << key; 00524 error("bla"); 00525 } 00526 00527 NodeVector* nextHop; 00528 00529 for (int i = fingerTable->getSize() - 1; i >= 0; i--) { 00530 if (fingerTable->getFinger(i).key.isBetweenLR(tempHandle.key, key)) { 00531 // is there a closer preceeding node in the successor list? 00532 //for (int j = successorList->getSize() - 1; j >= 0; j--) { 00533 if(!extendedFingerTable) { 00534 nextHop = new NodeVector(); 00535 // if (successorList->getSuccessor(j).key. 00536 // isBetween(fingerTable->getFinger(i).key, key)) { 00537 // nextHop->push_back(successorList->getSuccessor(j)); 00538 // } 00539 // else { 00540 // if no, settle with the node already found 00541 nextHop->push_back(fingerTable->getFinger(i)); 00542 //} 00543 00544 EV << "closestPreceedingNode: node " << thisNode 00545 << " for key " << key << " finger " 00546 << fingerTable->getFinger(i).key << " better than " 00547 << tempHandle.key << endl; 00548 return nextHop; 00549 } 00550 else { 00551 // if (successorList->getSuccessor(j).key. 00552 // isBetween(fingerTable->getFinger(i, key)->begin()->key, key)) { //TODO 00553 // nextHop = new NodeVector(); 00554 // nextHop->push_back(successorList->getSuccessor(j)); 00555 // return nextHop; 00556 // } 00557 // else { 00558 // if(*fingerTable->getFinger(i, key)->begin() != fingerTable->getFinger(i)) 00559 // std::cout << "thisNode.key =\t" << thisNode.key 00560 // << "\nfinger =\t" << fingerTable->getFinger(i).key 00561 // << "\nused = \t" << fingerTable->getFinger(i, key)->begin()->key 00562 // << "\ndestKey =\t" << key 00563 // << "\n" << std::endl; 00564 return fingerTable->getFinger(i, key); 00565 //} 00566 } 00567 //} 00568 } 00569 } 00570 00571 nextHop = new NodeVector(); 00572 00573 EV << "no finger found!!!" << endl; 00574 00575 // if no finger is found lookup the rest of the successor list 00576 for(int i = successorList->getSize() - 1; i >= 0 00577 && nextHop->size() <= numFingerCandidates ; i--) { 00578 if(successorList->getSuccessor(i).key.isBetween(thisNode.key, key)) { 00579 nextHop->push_back(successorList->getSuccessor(i)); 00580 //return nextHop; 00581 } 00582 } 00583 00584 if(nextHop->size() != 0) 00585 return nextHop; 00586 00587 // if this is the first and only node on the ring, it is responsible 00588 if ((predecessorNode.isUnspecified()) && 00589 (successorList->getSuccessor() == thisNode)) { 00590 nextHop->push_back(thisNode); 00591 return nextHop; 00592 } 00593 00594 // if there is still no node found return NodeHandle::UNSPECIFIED_NODE 00595 std::stringstream temp("Error in Chord::closestPreceedingNode()!\n"); 00596 temp << thisNode.key << " " << key; 00597 error(temp.str().c_str()); 00598 nextHop->push_back(NodeHandle::UNSPECIFIED_NODE); 00599 return nextHop; 00600 }
void Chord::findFriendModules | ( | ) | [protected, virtual] |
Assigns the finger table and succesesor list module to our reference.
Reimplemented in Koorde.
01076 { 01077 fingerTable = check_and_cast<ChordFingerTable*> 01078 (parentModule()->submodule("fingerTable")); 01079 01080 successorList = check_and_cast<ChordSuccessorList*> 01081 (parentModule()->submodule("successorList")); 01082 }
void Chord::initializeFriendModules | ( | ) | [protected, virtual] |
initializes finger table and successor list
Reimplemented in Koorde.
01087 { 01088 // initialize finger table 01089 fingerTable->initializeTable(thisNode.key.getLength(), thisNode, this); 01090 01091 // initialize successor list 01092 successorList->initializeList(par("successorListSize"), thisNode, this); 01093 }
bool Chord::handleRpc | ( | BaseCallMessage * | msg | ) | [protected, virtual] |
Processes Remote-Procedure-Call invokation messages.
Reimplemented from BaseRpc.
Reimplemented in Koorde.
00262 { 00263 if (state != READY) { 00264 // delete msg; 00265 // EV << "Chord::handleRpc(): Received RPC call " 00266 // << "and state != READY!" << endl; 00267 return false; 00268 } 00269 00270 // delegate messages 00271 RPC_SWITCH_START( msg ) 00272 // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> ) 00273 RPC_DELEGATE( Join, rpcJoin ); 00274 RPC_DELEGATE( Notify, rpcNotify ); 00275 RPC_DELEGATE( Stabilize, rpcStabilize ); 00276 RPC_DELEGATE( Fixfingers, rpcFixfingers ); 00277 RPC_SWITCH_END( ) 00278 00279 return RPC_HANDLED; 00280 }
NodeVector * Chord::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. | |
msg | A pointer to the BaseRouteMessage or FindNodeCall message of this lookup. |
Reimplemented from BaseOverlay.
Reimplemented in Koorde.
00446 { 00447 bool err; 00448 NodeVector* nextHop; 00449 00450 if (state != READY) 00451 return new NodeVector(); 00452 00453 // // example code for findNodeExt 00454 00455 // if (msg != NULL) { 00456 // if (!msg->hasObject("findNodeExt")) { 00457 // ChordFindNodeExtMessage *extMsg = 00458 // new ChordFindNodeExtMessage("findNodeExt"); 00459 // extMsg->setLength(8*10); 00460 // msg->addObject( extMsg ); 00461 // } 00462 // 00463 // ChordFindNodeExtMessage *extMsg = 00464 // (ChordFindNodeExtMessage*) msg->getObject("findNodeExt"); 00465 // 00466 // cout << "ChordCount: " << extMsg->getChordCount() + 1 << endl; 00467 // 00468 // extMsg->setChordCount(extMsg->getChordCount() + 1); 00469 // } 00470 00471 // if key is unspecified, the message is for this node 00472 if (key.isUnspecified()) { 00473 nextHop = new NodeVector(); 00474 nextHop->push_back(thisNode); 00475 } 00476 00477 // the message is destined for this node 00478 else if (isSiblingFor(thisNode, key, 1, &err)) { 00479 nextHop = new NodeVector(); 00480 nextHop->push_back(thisNode); 00481 for (uint i=0; i<successorList->getSize(); i++) { 00482 nextHop->push_back(successorList->getSuccessor(i)); 00483 } 00484 } 00485 00486 // the message destined for our successor 00487 else if (key.isBetweenR(thisNode.key, 00488 successorList->getSuccessor().key)) { 00489 nextHop = new NodeVector(); 00490 nextHop->push_back(successorList->getSuccessor()); 00491 } 00492 00493 // find next hop with finger table and/or successor list 00494 else { 00495 nextHop = closestPreceedingNode(key); 00496 } 00497 00498 if ((nextHop->size() > 0) && ((*nextHop)[0].key == thisNode.key)) { 00499 if (!isSiblingFor(thisNode, key, 1, &err)) { 00500 std::cout << "aaaaaaaaaaargh!" << endl; 00501 nextHop->clear(); 00502 } 00503 } 00504 00505 return nextHop; 00506 }
void Chord::joinOverlay | ( | ) | [protected, virtual] |
Reimplemented from BaseOverlay.
00119 { 00120 changeState(INIT); 00121 changeState(BOOTSTRAP); 00122 }
bool Chord::isSiblingFor | ( | const NodeHandle & | node, | |
const OverlayKey & | key, | |||
int | numSiblings, | |||
bool * | err | |||
) | [protected, virtual] |
Reimplemented from BaseOverlay.
00366 { 00367 if (key.isUnspecified()) 00368 error("Chord::isSiblingFor(): key is unspecified!"); 00369 00370 if (state != READY) { 00371 *err = true; 00372 return false; 00373 } 00374 00375 if (numSiblings > getMaxNumSiblings()) { 00376 opp_error("Chord::isSiblingFor(): numSiblings too big!"); 00377 } 00378 // set default number of siblings to consider 00379 if (numSiblings == -1) numSiblings = getMaxNumSiblings(); 00380 00381 // if this is the first and only node on the ring, it is responsible 00382 if ((predecessorNode.isUnspecified()) && (node == thisNode)) { 00383 if(successorList->isEmpty() || (node.key == key)) { 00384 *err = false; 00385 return true; 00386 } else { 00387 *err = true; 00388 return false; 00389 } 00390 } 00391 00392 if (key.isBetweenR(predecessorNode.key, thisNode.key)) { 00393 *err = false; 00394 return true; 00395 } 00396 00397 00398 NodeHandle prevNode = predecessorNode; 00399 NodeHandle curNode; 00400 00401 for (int i = -1; i < (int)successorList->getSize(); 00402 i++, prevNode = curNode) { 00403 00404 if (i < 0) { 00405 curNode = thisNode; 00406 } else { 00407 curNode = successorList->getSuccessor(i); 00408 } 00409 00410 if (node == curNode) { 00411 // is the message destined for curNode? 00412 if (key.isBetweenR(prevNode.key, curNode.key)) { 00413 if (numSiblings <= ((int)successorList->getSize() - i)) { 00414 *err = false; 00415 return true; 00416 } else { 00417 *err = true; 00418 return false; 00419 } 00420 } else { 00421 // the key doesn't directly belong to this node, but 00422 // the node could be in the replicaSet for this key 00423 if (numSiblings <= 1) { 00424 *err = false; 00425 return false; 00426 } else { 00427 // In Chord we don't know if we belong to the 00428 // replicaSet of one of our predecessors 00429 *err = true; 00430 return false; 00431 } 00432 } 00433 } 00434 } 00435 00436 // node is not in our neighborSet 00437 *err = true; 00438 return false; 00439 }
int Chord::getMaxNumSiblings | ( | ) | [protected, virtual] |
Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.
Reimplemented from BaseOverlay.
00352 { 00353 return successorListSize; 00354 }
int Chord::getMaxNumRedundantNodes | ( | ) | [protected, virtual] |
Query the maximum number of redundant next hop nodes that are returned by findNode().
Reimplemented from BaseOverlay.
00357 { 00358 return extendedFingerTable ? numFingerCandidates : 1; 00359 }
void Chord::rpcFixfingers | ( | FixfingersCall * | call | ) | [protected] |
Fixfingers Remote-Procedure-Call.
call | RPC Parameter Message |
01022 { 01023 FixfingersResponse* fixfingersResponse = 01024 new FixfingersResponse("FixfingersResponse"); 01025 01026 fixfingersResponse->setSucNodeArraySize(1); 01027 fixfingersResponse->setSucNode(0, thisNode); 01028 01029 if(extendedFingerTable) { 01030 fixfingersResponse->setSucNodeArraySize(((successorList->getSize() + 1 < numFingerCandidates + 1) 01031 ? successorList->getSize() + 1 : numFingerCandidates + 1)); 01032 for(unsigned int i = 0; i < (((successorList->getSize()) < numFingerCandidates) 01033 ? (successorList->getSize()) : numFingerCandidates); i++) { 01034 assert(!successorList->getSuccessor(i).isUnspecified()); 01035 fixfingersResponse->setSucNode(i + 1, successorList->getSuccessor(i)); 01036 } 01037 } 01038 fixfingersResponse->setFinger(call->getFinger()); 01039 fixfingersResponse->setLength(FIXFINGERSRESPONSE_L(fixfingersResponse)); //TODO 01040 01041 sendRpcResponse(call, fixfingersResponse); 01042 }
void Chord::rpcJoin | ( | JoinCall * | call | ) | [protected] |
Join Remote-Procedure-Call.
call | RPC Parameter Message |
00815 { 00816 NodeHandle requestor = joinCall->getSrcNode(); 00817 00818 // compile successor list 00819 JoinResponse* joinResponse = 00820 new JoinResponse("JoinResponse"); 00821 00822 int sucNum = successorList->getSize(); 00823 joinResponse->setSucNum(sucNum); 00824 joinResponse->setSucNodeArraySize(sucNum); 00825 00826 for (int k = 0; k < sucNum; k++) { 00827 joinResponse->setSucNode(k, successorList->getSuccessor(k)); 00828 } 00829 00830 // sent our predecessor as hint to the joining node 00831 if (predecessorNode.isUnspecified() && successorList->isEmpty()) { 00832 // we are the only node in the ring 00833 joinResponse->setPreNode(thisNode); 00834 } else { 00835 joinResponse->setPreNode(predecessorNode); 00836 } 00837 00838 joinResponse->setLength(JOINRESPONSE_L(joinResponse)); 00839 00840 sendRpcResponse(joinCall, joinResponse); 00841 00842 if (aggressiveJoinMode) { 00843 // aggressiveJoinMode differs from standard join operations: 00844 // 1. set our predecessor pointer to the joining node 00845 // 2. send our old predecessor as hint in JoinResponse msgs 00846 // 3. send a NEWSUCCESSORHINT to our old predecessor to update 00847 // its successor pointer 00848 00849 // send NEWSUCCESSORHINT to our old predecessor 00850 00851 if (!predecessorNode.isUnspecified()) { 00852 NewSuccessorHintMessage* newSuccessorHintMsg = 00853 new NewSuccessorHintMessage("NEWSUCCESSORHINT"); 00854 newSuccessorHintMsg->setCommand(NEWSUCCESSORHINT); 00855 00856 newSuccessorHintMsg->setSrcNode(thisNode); 00857 newSuccessorHintMsg->setPreNode(requestor); 00858 newSuccessorHintMsg->setLength( 00859 NEWSUCCESSORHINT_L(newSuccessorHintMsg)); 00860 00861 sendMessageToUDP(predecessorNode, newSuccessorHintMsg); 00862 } 00863 00864 if (predecessorNode.isUnspecified() || (predecessorNode != requestor)) { 00865 // send update to application if we've got a new predecessor 00866 if (!predecessorNode.isUnspecified()) { 00867 callUpdate(predecessorNode, false); 00868 } 00869 callUpdate(requestor, true); 00870 00871 // the requestor is our new predecessor 00872 predecessorNode = requestor; 00873 } 00874 } 00875 00876 // if we don't have a successor, the requestor is also our new successor 00877 if (successorList->isEmpty()) 00878 successorList->addSuccessor(requestor); 00879 00880 updateTooltip(); 00881 }
void Chord::rpcNotify | ( | NotifyCall * | call | ) | [protected] |
NOTIFY Remote-Procedure-Call.
call | RPC Parameter Message |
Reimplemented in Koorde.
00965 { 00966 // our predecessor seems to be alive 00967 missingPredecessorStabRequests = 0; 00968 00969 NodeHandle newPredecessor = call->getSrcNode(); 00970 00971 // is the new predecessor closer than the current one? 00972 if (predecessorNode.isUnspecified() || 00973 newPredecessor.key.isBetween(predecessorNode.key, thisNode.key)) { 00974 00975 if ((predecessorNode.isUnspecified()) || 00976 (newPredecessor != predecessorNode)) { 00977 // send update to application if we've got a new predecessor 00978 if (!predecessorNode.isUnspecified()) { 00979 callUpdate(predecessorNode, false); 00980 } 00981 callUpdate(newPredecessor, true); 00982 00983 // set up new predecessor 00984 predecessorNode = newPredecessor; 00985 updateTooltip(); 00986 } 00987 } 00988 00989 // compile NOTIFY response 00990 NotifyResponse* notifyResponse = new NotifyResponse("NotifyResponse"); 00991 00992 int sucNum = successorList->getSize(); 00993 notifyResponse->setSucNum(sucNum); 00994 notifyResponse->setSucNodeArraySize(sucNum); 00995 00996 for (int k = 0; k < sucNum; k++) { 00997 notifyResponse->setSucNode(k, successorList->getSuccessor(k)); 00998 } 00999 01000 notifyResponse->setLength(NOTIFYRESPONSE_L(notifyResponse)); 01001 01002 sendRpcResponse(call, notifyResponse); 01003 }
void Chord::rpcStabilize | ( | StabilizeCall * | call | ) | [protected] |
STABILIZE Remote-Procedure-Call.
call | RPC Parameter Message |
00926 { 00927 // our predecessor seems to be alive 00928 missingPredecessorStabRequests = 0; 00929 00930 // reply with StabilizeResponse message 00931 StabilizeResponse* stabilizeResponse = 00932 new StabilizeResponse("StabilizeResponse"); 00933 stabilizeResponse->setPreNode(predecessorNode); 00934 stabilizeResponse->setLength(STABILIZERESPONSE_L(stabilizeResponse)); 00935 00936 sendRpcResponse(call, stabilizeResponse); 00937 }
void Chord::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.
Reimplemented in Koorde.
00284 { 00285 RPC_SWITCH_START(msg) 00286 RPC_ON_RESPONSE( Ping ) { 00287 handleRpcPingResponse(_PingResponse, rpcId, rtt); 00288 EV << "Ping RPC Response received: id=" << rpcId 00289 << " msg=" << *_PingResponse << " rtt=" << rtt << endl; 00290 break; 00291 } 00292 RPC_ON_RESPONSE( Join ) { 00293 handleRpcJoinResponse(_JoinResponse); 00294 EV << "Join RPC Response received: id=" << rpcId 00295 << " msg=" << *_JoinResponse << " rtt=" << rtt << endl; 00296 break; 00297 } 00298 RPC_ON_RESPONSE( Notify ) { 00299 handleRpcNotifyResponse(_NotifyResponse); 00300 EV << "Notify RPC Response received: id=" << rpcId 00301 << " msg=" << *_NotifyResponse << " rtt=" << rtt << endl; 00302 break; 00303 } 00304 RPC_ON_RESPONSE( Stabilize ) { 00305 handleRpcStabilizeResponse(_StabilizeResponse); 00306 EV << "Stabilize RPC Response received: id=" << rpcId 00307 << " msg=" << *_StabilizeResponse << " rtt=" << rtt << endl; 00308 break; 00309 } 00310 RPC_ON_RESPONSE( Fixfingers ) { 00311 handleRpcFixfingersResponse(_FixfingersResponse, rtt); 00312 EV << "Fixfingers RPC Response received: id=" << rpcId 00313 << " msg=" << *_FixfingersResponse << " rtt=" << rtt << endl; 00314 break; 00315 } 00316 RPC_SWITCH_END( ) 00317 }
void Chord::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
int | rpcId | |||
) | [protected, virtual] |
This method is called if an RPC timeout has been reached.
msg | The original RPC message. | |
dest | The destination of the RPC | |
rpcId | The RPC id. |
Reimplemented from RpcListener.
00321 { 00322 RPC_SWITCH_START(msg) 00323 RPC_ON_CALL( FindNode ) { 00324 EV << "FindNode RPC Call timed out: id=" << rpcId 00325 << " msg=" << *_FindNodeCall << endl; 00326 break; 00327 } 00328 RPC_ON_CALL( Join ) { 00329 EV << "Join RPC Call timed out: id=" << rpcId 00330 << " msg=" << *_JoinCall << endl; 00331 break; 00332 } 00333 RPC_ON_CALL( Notify ) { 00334 EV << "Notify RPC Call timed out: id=" << rpcId 00335 << " msg=" << *_NotifyCall << endl; 00336 break; 00337 } 00338 RPC_ON_CALL( Stabilize ) { 00339 EV << "Stabilize RPC Call timed out: id=" << rpcId 00340 << " msg=" << *_StabilizeCall << endl; 00341 break; 00342 } 00343 RPC_ON_CALL( Fixfingers ) { 00344 EV << "Fixfingers RPC Call timed out: id=" << rpcId 00345 << " msg=" << *_FixfingersCall << endl; 00346 break; 00347 } 00348 RPC_SWITCH_END( ) 00349 }
void Chord::handleRpcJoinResponse | ( | JoinResponse * | joinResponse | ) | [protected, virtual] |
Reimplemented in Koorde.
00884 { 00885 // determine the numer of successor nodes to add 00886 int sucNum = successorListSize - 1; 00887 00888 if (joinResponse->getSucNum() < successorListSize - 1) { 00889 sucNum = joinResponse->getSucNum(); 00890 } 00891 00892 // add successor node(s) 00893 for (int k = 0; k < sucNum; k++) { 00894 NodeHandle successor = joinResponse->getSucNode(k); 00895 successorList->addSuccessor(successor); 00896 } 00897 00898 // \todo {check commented out addSuccessor (Schenk)} 00899 //successorList->addSuccessor(joinResponse->getSrcNode()); 00900 00901 // the sender of this message is our new successor 00902 successorList->addSuccessor(joinResponse->getSrcNode()); 00903 00904 // in aggressiveJoinMode: use hint in JoinResponse 00905 // to set our new predecessor 00906 if (aggressiveJoinMode) { 00907 predecessorNode = joinResponse->getPreNode(); 00908 callUpdate(predecessorNode, true); 00909 } 00910 00911 updateTooltip(); 00912 00913 changeState(READY); 00914 00915 // immediate stabilization protocol 00916 cancelEvent(stabilize_timer); 00917 scheduleAt(simulation.simTime(), stabilize_timer); 00918 00919 // immediate finger repair protocol 00920 cancelEvent(fixfingers_timer); 00921 scheduleAt(simulation.simTime(), fixfingers_timer); 00922 }
void Chord::handleRpcNotifyResponse | ( | NotifyResponse * | notifyResponse | ) | [protected, virtual] |
Reimplemented in Koorde.
01007 { 01008 if (successorList->getSuccessor() != notifyResponse->getSrcNode()) { 01009 EV << "Chord::handleRpcNotifyResponse: The srcNode of the received " 01010 << "NotifyResponse is not our current successor!" << endl; 01011 return; 01012 } 01013 01014 // replace our successor list by our successor's successor list 01015 successorList->updateList(notifyResponse); 01016 01017 updateTooltip(); 01018 }
void Chord::handleRpcStabilizeResponse | ( | StabilizeResponse * | stabilizeResponse | ) | [protected, virtual] |
Reimplemented in Koorde.
00940 { 00941 // our successor seems to be alive 00942 missingSuccessorStabResponses = 0; 00943 00944 // fetch the successor's predecessor 00945 NodeHandle predecessor = stabilizeResponse->getPreNode(); 00946 00947 // is the successor's predecessor a new successor for this node? 00948 if (successorList->isEmpty() || 00949 predecessor.key.isBetween(thisNode.key, 00950 successorList->getSuccessor().key)) { 00951 // add the successor's predecessor to the successor list 00952 successorList->addSuccessor(predecessor); 00953 updateTooltip(); 00954 } 00955 00956 // compile NOTIFY RPC 00957 NotifyCall* notifyCall = new NotifyCall("NotifyCall"); 00958 notifyCall->setLength(NOTIFYCALL_L(notifyCall)); 00959 00960 sendRpcMessage(successorList->getSuccessor(), notifyCall); 00961 }
void Chord::handleRpcFixfingersResponse | ( | FixfingersResponse * | fixfingersResponse, | |
double | rtt = -1 | |||
) | [protected, virtual] |
01046 { 01047 // set new finger pointer# 01048 if(!extendedFingerTable) 01049 fingerTable->setFinger(fixfingersResponse->getFinger(), fixfingersResponse->getSucNode(0)); 01050 01051 else { 01052 Successors successors; 01053 successors.insert(std::make_pair(rtt, fixfingersResponse->getSucNode(0))); 01054 01055 for(unsigned int i = 1; i < fixfingersResponse->getSucNodeArraySize(); i++) { 01056 if(fixfingersResponse->getSucNode(i).isUnspecified()) 01057 continue; 01058 if(fixfingersResponse->getSucNode(i) == thisNode) 01059 break; 01060 successors.insert(std::make_pair(DBL_MAX, fixfingersResponse->getSucNode(i))); 01061 if(proximityRouting) 01062 pingNode(fixfingersResponse->getSucNode(i), -1, 0, NULL, NULL, 01063 fixfingersResponse->getFinger()); 01064 } 01065 fingerTable->setFinger(fixfingersResponse->getFinger(), successors); 01066 } 01067 }
void Chord::handleRpcPingResponse | ( | PingResponse * | pingResponse, | |
int | id, | |||
double | rtt | |||
) | [protected, virtual] |
void Chord::predecessorIsDead | ( | ) | [protected, virtual] |
void Chord::successorIsDead | ( | ) | [protected, virtual] |
friend class ChordSuccessorList [friend] |
int Chord::joinRetry [protected] |
int Chord::stabilizeRetry [protected] |
// retries before neighbor considered failed
double Chord::joinDelay [protected] |
double Chord::stabilizeDelay [protected] |
stabilize interval (secs)
double Chord::fixfingersDelay [protected] |
int Chord::successorListSize [protected] |
bool Chord::aggressiveJoinMode [protected] |
use modified (faster) JOIN protocol
bool Chord::extendedFingerTable [protected] |
unsigned int Chord::numFingerCandidates [protected] |
bool Chord::proximityRouting [protected] |
cMessage* Chord::join_timer [protected] |
cMessage* Chord::stabilize_timer [protected] |
cMessage* Chord::fixfingers_timer [protected] |
int Chord::joinCount [protected] |
int Chord::stabilizeCount [protected] |
int Chord::fixfingersCount [protected] |
int Chord::notifyCount [protected] |
int Chord::newsuccessorhintCount [protected] |
int Chord::joinBytesSent [protected] |
int Chord::stabilizeBytesSent [protected] |
int Chord::notifyBytesSent [protected] |
int Chord::fixfingersBytesSent [protected] |
int Chord::newsuccessorhintBytesSent [protected] |
int Chord::state [protected] |
current node state
int Chord::keyLength [protected] |
length of an overlay key in bits
int Chord::missingPredecessorStabRequests [protected] |
missing StabilizeCall msgs
int Chord::missingSuccessorStabResponses [protected] |
missing StabilizeResponse msgs
NodeHandle Chord::predecessorNode [protected] |
predecessor of this node
NodeHandle Chord::bootstrapNode [protected] |
node used to bootrap
ChordFingerTable* Chord::fingerTable [protected] |
pointer to this node's finger table
ChordSuccessorList* Chord::successorList [protected] |
pointer to this node's successor list