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