#include <Chord.h>
Public Member Functions | |
| Chord () | |
| virtual | ~Chord () |
| virtual void | initializeOverlay (int stage) |
| virtual void | handleTimerEvent (cMessage *msg) |
| virtual void | handleUDPMessage (BaseOverlayMessage *msg) |
| virtual void | recordOverlaySentStats (BaseOverlayMessage *msg) |
| virtual void | finishOverlay () |
| OverlayKey | distance (const OverlayKey &x, const OverlayKey &y, bool useAlternative=false) const |
| virtual void | updateTooltip () |
| updates information shown in tk-environment | |
| void | proxCallback (const TransportAddress &node, int rpcId, cPolymorphic *contextPointer, Prox prox) |
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 successor list module to our reference. | |
| virtual void | initializeFriendModules () |
| initializes finger table and successor list | |
| virtual bool | handleRpcCall (BaseCallMessage *msg) |
| NodeVector * | findNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg) |
| virtual void | joinOverlay () |
| virtual void | joinForeignPartition (const NodeHandle &node) |
| virtual bool | isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err) |
| int | getMaxNumSiblings () |
| int | getMaxNumRedundantNodes () |
| void | rpcFixfingers (FixfingersCall *call) |
| Fixfingers Remote-Procedure-Call. | |
| virtual void | rpcJoin (JoinCall *call) |
| Join Remote-Procedure-Call. | |
| virtual void | rpcNotify (NotifyCall *call) |
| NOTIFY Remote-Procedure-Call. | |
| void | rpcStabilize (StabilizeCall *call) |
| STABILIZE Remote-Procedure-Call. | |
| virtual void | handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt) |
| virtual void | handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey) |
| virtual void | pingResponse (PingResponse *pingResponse, cPolymorphic *context, int rpcId, simtime_t rtt) |
| virtual void | pingTimeout (PingCall *pingCall, const TransportAddress &dest, cPolymorphic *context, int rpcId) |
| virtual void | handleRpcJoinResponse (JoinResponse *joinResponse) |
| virtual void | handleRpcNotifyResponse (NotifyResponse *notifyResponse) |
| virtual void | handleRpcStabilizeResponse (StabilizeResponse *stabilizeResponse) |
| virtual void | handleRpcFixfingersResponse (FixfingersResponse *fixfingersResponse, double rtt=-1) |
| virtual bool | handleFailedNode (const TransportAddress &failed) |
Protected Attributes | |
| int | joinRetry |
| int | stabilizeRetry |
| // retries before neighbor considered failed | |
| double | joinDelay |
| double | stabilizeDelay |
| stabilize interval (secs) | |
| double | fixfingersDelay |
| double | checkPredecessorDelay |
| int | successorListSize |
| bool | aggressiveJoinMode |
| use modified (faster) JOIN protocol | |
| bool | extendedFingerTable |
| unsigned int | numFingerCandidates |
| bool | proximityRouting |
| bool | memorizeFailedSuccessor |
| bool | newChordFingerTable |
| bool | mergeOptimizationL1 |
| bool | mergeOptimizationL2 |
| bool | mergeOptimizationL3 |
| bool | mergeOptimizationL4 |
| cMessage * | join_timer |
| cMessage * | stabilize_timer |
| cMessage * | fixfingers_timer |
| cMessage * | checkPredecessor_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 | |
| NodeHandle | predecessorNode |
| predecessor of this node | |
| TransportAddress | bootstrapNode |
| node used to bootstrap | |
| ChordFingerTable * | fingerTable |
| pointer to this node's finger table | |
| ChordSuccessorList * | successorList |
| pointer to this node's successor list | |
Private Attributes | |
| TransportAddress | failedSuccessor |
Friends | |
| class | ChordSuccessorList |
| class | ChordFingerTable |
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.
Definition at line 47 of file Chord.h.
| oversim::Chord::Chord | ( | ) |
Definition at line 38 of file Chord.cc.
{
stabilize_timer = fixfingers_timer = join_timer = NULL;
fingerTable = NULL;
| oversim::Chord::~Chord | ( | ) | [virtual] |
Definition at line 116 of file Chord.cc.
{
// destroy self timer messages
cancelAndDelete(join_timer);
cancelAndDelete(stabilize_timer);
cancelAndDelete(fixfingers_timer);
cancelAndDelete(checkPredecessor_timer);
| void oversim::Chord::changeState | ( | int | toState | ) | [protected, virtual] |
changes node state
| toState | state to change to |
Reimplemented in oversim::Koorde.
Definition at line 151 of file Chord.cc.
Referenced by handleJoinTimerExpired(), handleRpcJoinResponse(), and joinOverlay().
{
//
// Defines tasks to be executed when a state change occurs.
//
switch (toState) {
case INIT:
state = INIT;
setOverlayReady(false);
// initialize predecessor pointer
predecessorNode = NodeHandle::UNSPECIFIED_NODE;
// initialize finger table and successor list
initializeFriendModules();
updateTooltip();
// debug message
if (debugOutput) {
EV << "[Chord::changeState() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Entered INIT stage"
<< endl;
}
getParentModule()->getParentModule()->bubble("Enter INIT state.");
break;
case BOOTSTRAP:
state = BOOTSTRAP;
// initiate bootstrap process
cancelEvent(join_timer);
// workaround: prevent notificationBoard from taking
// ownership of join_timer message
take(join_timer);
scheduleAt(simTime(), join_timer);
// debug message
if (debugOutput) {
EV << "[Chord::changeState() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Entered BOOTSTRAP stage"
<< endl;
}
getParentModule()->getParentModule()->bubble("Enter BOOTSTRAP state.");
// find a new bootstrap node and enroll to the bootstrap list
bootstrapNode = bootstrapList->getBootstrapNode();
// is this the first node?
if (bootstrapNode.isUnspecified()) {
// create new cord ring
assert(predecessorNode.isUnspecified());
bootstrapNode = thisNode;
changeState(READY);
updateTooltip();
}
break;
case READY:
state = READY;
setOverlayReady(true);
// initiate stabilization protocol
cancelEvent(stabilize_timer);
scheduleAt(simTime() + stabilizeDelay, stabilize_timer);
// initiate finger repair protocol
cancelEvent(fixfingers_timer);
scheduleAt(simTime() + fixfingersDelay,
fixfingers_timer);
// initiate predecessor check
cancelEvent(checkPredecessor_timer);
if (checkPredecessorDelay > 0) {
scheduleAt(simTime() + checkPredecessorDelay,
checkPredecessor_timer);
}
// debug message
if (debugOutput) {
EV << "[Chord::changeState() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Entered READY stage"
<< endl;
}
getParentModule()->getParentModule()->bubble("Enter READY state.");
break;
}
| NodeVector * oversim::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 |
Definition at line 601 of file Chord.cc.
Referenced by findNode().
{
NodeHandle tempHandle = NodeHandle::UNSPECIFIED_NODE;
// find the closest preceding node in the successor list
for (int j = successorList->getSize() - 1; j >= 0; j--) {
// return a predecessor of the key, unless we know a node with an Id = destKey
if (successorList->getSuccessor(j).getKey().isBetweenR(thisNode.getKey(), key)) {
tempHandle = successorList->getSuccessor(j);
break;
}
}
if(tempHandle.isUnspecified()) {
std::stringstream temp;
temp << "Chord::closestPreceedingNode(): Successor list broken "
<< thisNode.getKey() << " " << key;
throw cRuntimeError(temp.str().c_str());
}
NodeVector* nextHop = NULL;
for (int i = fingerTable->getSize() - 1; i >= 0; i--) {
// return a predecessor of the key, unless we know a node with an Id = destKey
if (fingerTable->getFinger(i).getKey().isBetweenLR(tempHandle.getKey(), key)) {
if(!extendedFingerTable) {
nextHop = new NodeVector();
nextHop->push_back(fingerTable->getFinger(i));
EV << "[Chord::closestPreceedingNode() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " ClosestPreceedingNode: node " << thisNode
<< " for key " << key << "\n"
<< " finger " << fingerTable->getFinger(i).getKey()
<< " better than \n"
<< " " << tempHandle.getKey()
<< endl;
return nextHop;
} else {
return fingerTable->getFinger(i, key);
}
}
}
nextHop = new NodeVector();
EV << "[Chord::closestPreceedingNode() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " No finger found"
<< endl;
// if no finger is found lookup the rest of the successor list
for (int i = successorList->getSize() - 1; i >= 0
&& nextHop->size() <= numFingerCandidates ; i--) {
if (successorList->getSuccessor(i).getKey().isBetween(thisNode.getKey(), key)) {
nextHop->push_back(successorList->getSuccessor(i));
}
}
if (nextHop->size() != 0) {
return nextHop;
}
// if this is the first and only node on the ring, it is responsible
if ((predecessorNode.isUnspecified()) &&
(successorList->getSuccessor() == thisNode)) {
nextHop->push_back(thisNode);
return nextHop;
}
// if there is still no node found throw an exception
throw cRuntimeError("Error in Chord::closestPreceedingNode()!");
return nextHop;
| OverlayKey oversim::Chord::distance | ( | const OverlayKey & | x, | |
| const OverlayKey & | y, | |||
| bool | useAlternative = false | |||
| ) | const |
| void oversim::Chord::findFriendModules | ( | ) | [protected, virtual] |
Assigns the finger table and successor list module to our reference.
Reimplemented in oversim::Koorde.
Definition at line 1358 of file Chord.cc.
Referenced by initializeOverlay().
{
fingerTable = check_and_cast<ChordFingerTable*>
(getParentModule()->getSubmodule("fingerTable"));
successorList = check_and_cast<ChordSuccessorList*>
(getParentModule()->getSubmodule("successorList"));
| NodeVector * oversim::Chord::findNode | ( | const OverlayKey & | key, | |
| int | numRedundantNodes, | |||
| int | numSiblings, | |||
| BaseOverlayMessage * | msg | |||
| ) | [protected] |
Reimplemented in oversim::Koorde.
Definition at line 547 of file Chord.cc.
{
bool err;
NodeVector* nextHop;
if (state != READY)
return new NodeVector();
if (successorList->isEmpty() && !predecessorNode.isUnspecified()) {
throw new cRuntimeError("Chord: Node is READY, has a "
"predecessor but no successor!");
join();
return new NodeVector();
}
// if key is unspecified, the message is for this node
if (key.isUnspecified()) {
nextHop = new NodeVector();
nextHop->push_back(thisNode);
}
// the message is destined for this node
else if (isSiblingFor(thisNode, key, 1, &err)) {
nextHop = new NodeVector();
nextHop->push_back(thisNode);
for (uint32_t i = 0; i < successorList->getSize(); i++) {
nextHop->push_back(successorList->getSuccessor(i));
}
nextHop->downsizeTo(numSiblings);
}
// the message destined for our successor
else if (key.isBetweenR(thisNode.getKey(),
successorList->getSuccessor().getKey())) {
nextHop = new NodeVector();
for (uint32_t i = 0; i < successorList->getSize(); i++) {
nextHop->push_back(successorList->getSuccessor(i));
}
nextHop->downsizeTo(numRedundantNodes);
}
// find next hop with finger table and/or successor list
else {
nextHop = closestPreceedingNode(key);
nextHop->downsizeTo(numRedundantNodes);
}
return nextHop;
| void oversim::Chord::finishOverlay | ( | ) | [virtual] |
Reimplemented in oversim::Koorde.
Definition at line 725 of file Chord.cc.
{
// remove this node from the bootstrap list
bootstrapList->removeBootstrapNode(thisNode);
simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
if (time < GlobalStatistics::MIN_MEASURED) return;
globalStatistics->addStdDev("Chord: Sent JOIN Messages/s",
joinCount / time);
globalStatistics->addStdDev("Chord: Sent NEWSUCCESSORHINT Messages/s",
newsuccessorhintCount / time);
globalStatistics->addStdDev("Chord: Sent STABILIZE Messages/s",
stabilizeCount / time);
globalStatistics->addStdDev("Chord: Sent NOTIFY Messages/s",
notifyCount / time);
globalStatistics->addStdDev("Chord: Sent FIX_FINGERS Messages/s",
fixfingersCount / time);
globalStatistics->addStdDev("Chord: Sent JOIN Bytes/s",
joinBytesSent / time);
globalStatistics->addStdDev("Chord: Sent NEWSUCCESSORHINT Bytes/s",
newsuccessorhintBytesSent / time);
globalStatistics->addStdDev("Chord: Sent STABILIZE Bytes/s",
stabilizeBytesSent / time);
globalStatistics->addStdDev("Chord: Sent NOTIFY Bytes/s",
notifyBytesSent / time);
globalStatistics->addStdDev("Chord: Sent FIX_FINGERS Bytes/s",
fixfingersBytesSent / time);
| int oversim::Chord::getMaxNumRedundantNodes | ( | ) | [protected] |
Definition at line 415 of file Chord.cc.
{
return extendedFingerTable ? numFingerCandidates : 1;
| int oversim::Chord::getMaxNumSiblings | ( | ) | [protected] |
| bool oversim::Chord::handleFailedNode | ( | const TransportAddress & | failed | ) | [protected, virtual] |
Reimplemented in oversim::Koorde.
Definition at line 501 of file Chord.cc.
Referenced by handleRpcTimeout(), pingTimeout(), and proxCallback().
{
Enter_Method_Silent();
if (!predecessorNode.isUnspecified() && failed == predecessorNode)
predecessorNode = NodeHandle::UNSPECIFIED_NODE;
//TODO const reference -> trying to compare unspec NH
TransportAddress oldSuccessor = successorList->getSuccessor();
if (successorList->handleFailedNode(failed))
updateTooltip();
// check pointer for koorde
if (fingerTable != NULL)
fingerTable->handleFailedNode(failed);
// if we had a ring consisting of 2 nodes and our successor seems
// to be dead. Remove also predecessor because the successor
// and predecessor are the same node
if ((!predecessorNode.isUnspecified()) &&
oldSuccessor == predecessorNode) {
predecessorNode = NodeHandle::UNSPECIFIED_NODE;
callUpdate(predecessorNode, false);
}
if (failed == oldSuccessor) {
// schedule next stabilization process
if (memorizeFailedSuccessor) {
failedSuccessor = oldSuccessor;
}
cancelEvent(stabilize_timer);
scheduleAt(simTime(), stabilize_timer);
}
if (state != READY) return true;
if (successorList->isEmpty()) {
// lost our last successor - cancel periodic stabilize tasks
// and wait for rejoin
cancelEvent(stabilize_timer);
cancelEvent(fixfingers_timer);
}
return !(successorList->isEmpty());
| void oversim::Chord::handleFixFingersTimerExpired | ( | cMessage * | msg | ) | [protected, virtual] |
handle a expired fix_fingers timer
| msg | the timer self-message |
Definition at line 844 of file Chord.cc.
Referenced by oversim::Koorde::handleTimerEvent(), and handleTimerEvent().
{
if ((state != READY) || successorList->isEmpty())
return;
OverlayKey offset, lookupKey;
for (uint32_t nextFinger = 0; nextFinger < thisNode.getKey().getLength();
nextFinger++) {
// calculate "n + 2^(i - 1)"
offset = OverlayKey::pow2(nextFinger);
lookupKey = thisNode.getKey() + offset;
// send message only for non-trivial fingers
if (offset > successorList->getSuccessor().getKey() - thisNode.getKey()) {
// call FIXFINGER RPC
FixfingersCall* call = new FixfingersCall("FixfingersCall");
call->setFinger(nextFinger);
call->setBitLength(FIXFINGERSCALL_L(call));
sendRouteRpcCall(OVERLAY_COMP, lookupKey, call, NULL,
DEFAULT_ROUTING, fixfingersDelay);
} else {
// delete trivial fingers (points to the successor node)
fingerTable->removeFinger(nextFinger);
}
}
// schedule next finger repair process
cancelEvent(fixfingers_timer);
scheduleAt(simTime() + fixfingersDelay, msg);
| void oversim::Chord::handleJoinTimerExpired | ( | cMessage * | msg | ) | [protected, virtual] |
handle a expired join timer
| msg | the timer self-message |
Definition at line 757 of file Chord.cc.
Referenced by handleTimerEvent().
{
// only process timer, if node is not bootstrapped yet
if (state == READY)
return;
// enter state BOOTSTRAP
if (state != BOOTSTRAP)
changeState(BOOTSTRAP);
// change bootstrap node from time to time
joinRetry--;
if (joinRetry == 0) {
joinRetry = par("joinRetry");
changeState(BOOTSTRAP);
return;
}
// call JOIN RPC
JoinCall* call = new JoinCall("JoinCall");
call->setBitLength(JOINCALL_L(call));
RoutingType routingType = (defaultRoutingType == FULL_RECURSIVE_ROUTING ||
defaultRoutingType == RECURSIVE_SOURCE_ROUTING) ?
SEMI_RECURSIVE_ROUTING : defaultRoutingType;
sendRouteRpcCall(OVERLAY_COMP, bootstrapNode, thisNode.getKey(),
call, NULL, routingType, joinDelay);
// schedule next bootstrap process in the case this one fails
cancelEvent(join_timer);
scheduleAt(simTime() + joinDelay, msg);
| void oversim::Chord::handleNewSuccessorHint | ( | ChordMessage * | chordMsg | ) | [protected, virtual] |
handle a received NEWSUCCESSORHINT message
| chordMsg | the message to process |
Definition at line 877 of file Chord.cc.
Referenced by handleUDPMessage().
{
NewSuccessorHintMessage* newSuccessorHintMsg =
check_and_cast<NewSuccessorHintMessage*>(chordMsg);
// fetch the successor's predecessor
NodeHandle predecessor = newSuccessorHintMsg->getPreNode();
// is the successor's predecessor a new successor for this node?
if (predecessor.getKey().isBetween(thisNode.getKey(),
successorList->getSuccessor().getKey())
|| (thisNode.getKey() == successorList->getSuccessor().getKey())) {
// add the successor's predecessor to the successor list
successorList->addSuccessor(predecessor);
updateTooltip();
}
// if the successor node reports a new successor, put it into the
// successor list and start stabilizing
if (mergeOptimizationL3) {
if (successorList->getSuccessor() == predecessor) {
StabilizeCall *call = new StabilizeCall("StabilizeCall");
call->setBitLength(STABILIZECALL_L(call));
sendUdpRpcCall(predecessor, call);
} else {
if (successorList->getSuccessor() == newSuccessorHintMsg->
getSrcNode()) {
StabilizeCall *call = new StabilizeCall("StabilizeCall");
call->setBitLength(STABILIZECALL_L(call));
sendUdpRpcCall(predecessor, call);
}
}
}
| bool oversim::Chord::handleRpcCall | ( | BaseCallMessage * | msg | ) | [protected, virtual] |
Reimplemented in oversim::Koorde.
Definition at line 293 of file Chord.cc.
{
if (state != READY) {
EV << "[Chord::handleRpcCall() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Received RPC call and state != READY"
<< endl;
return false;
}
// delegate messages
RPC_SWITCH_START( msg )
// RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
RPC_DELEGATE( Join, rpcJoin );
RPC_DELEGATE( Notify, rpcNotify );
RPC_DELEGATE( Stabilize, rpcStabilize );
RPC_DELEGATE( Fixfingers, rpcFixfingers );
RPC_SWITCH_END( )
return RPC_HANDLED;
| void oversim::Chord::handleRpcFixfingersResponse | ( | FixfingersResponse * | fixfingersResponse, | |
| double | rtt = -1 | |||
| ) | [protected, virtual] |
Definition at line 1256 of file Chord.cc.
Referenced by handleRpcResponse().
{
/*
OverlayCtrlInfo* ctrlInfo =
check_and_cast<OverlayCtrlInfo*>(fixfingersResponse->getControlInfo());
RECORD_STATS(globalStatistics->recordOutVector("Chord: FIX_FINGERS response Hop Count", ctrlInfo->getHopCount()));
*/
// set new finger pointer#
if (!extendedFingerTable) {
fingerTable->setFinger(fixfingersResponse->getFinger(),
fixfingersResponse->getSucNode(0));
} else {
Successors successors;
for (unsigned int i = 0; i < fixfingersResponse->getSucNodeArraySize();
i++) {
if (fixfingersResponse->getSucNode(i).isUnspecified())
continue;
if (fixfingersResponse->getSucNode(i) == thisNode)
break;
successors.insert(std::make_pair(MAXTIME,
fixfingersResponse->getSucNode(i)));
}
if (successors.size() == 0) {
return;
}
fingerTable->setFinger(fixfingersResponse->getFinger(), successors);
#if 0
if (proximityRouting || globalParameters->getTopologyAdaptation()) {
#else
if (proximityRouting) {
#endif
for (unsigned int i = 0;
i < fixfingersResponse->getSucNodeArraySize();
i++) {
if (fixfingersResponse->getSucNode(i).isUnspecified())
continue;
if (fixfingersResponse->getSucNode(i) == thisNode)
break;
//pingNode(fixfingersResponse->getSucNode(i), -1, 0, NULL,
// NULL, NULL, fixfingersResponse->getFinger(),
// INVALID_TRANSPORT);
Prox prox =
neighborCache->getProx(fixfingersResponse->getSucNode(i),
NEIGHBORCACHE_DEFAULT,
fixfingersResponse->getFinger(),
this, NULL);
if (prox == Prox::PROX_TIMEOUT) {
fingerTable->removeFinger(fixfingersResponse->getFinger());
} else if (prox != Prox::PROX_UNKNOWN &&
prox != Prox::PROX_SELF) {
fingerTable->updateFinger(fixfingersResponse->getFinger(),
fixfingersResponse->getSucNode(i),
prox.proximity);
}
}
}
}
| void oversim::Chord::handleRpcJoinResponse | ( | JoinResponse * | joinResponse | ) | [protected, virtual] |
Reimplemented in oversim::Koorde.
Definition at line 987 of file Chord.cc.
Referenced by handleRpcResponse().
{
// determine the numer of successor nodes to add
int sucNum = successorListSize - 1;
if (joinResponse->getSucNum() < successorListSize - 1) {
sucNum = joinResponse->getSucNum();
}
// add successor getNode(s)
for (int k = 0; k < sucNum; k++) {
NodeHandle successor = joinResponse->getSucNode(k);
successorList->addSuccessor(successor);
}
// the sender of this message is our new successor
successorList->addSuccessor(joinResponse->getSrcNode());
// in aggressiveJoinMode: use hint in JoinResponse
// to set our new predecessor
if (aggressiveJoinMode) {
// it is possible that the joinResponse doesn't contain a valid
// predecessor especially when merging two partitions
if (!joinResponse->getPreNode().isUnspecified()) {
if (!predecessorNode.isUnspecified()) {
// inform the original predecessor about the new predecessor
if (mergeOptimizationL2) {
NewSuccessorHintMessage* newSuccessorHintMsg =
new NewSuccessorHintMessage("NEWSUCCESSORHINT");
newSuccessorHintMsg->setCommand(NEWSUCCESSORHINT);
newSuccessorHintMsg->setSrcNode(thisNode);
newSuccessorHintMsg->setPreNode(joinResponse->getPreNode());
newSuccessorHintMsg->
setBitLength(NEWSUCCESSORHINT_L(newSuccessorHintMsg));
sendMessageToUDP(predecessorNode, newSuccessorHintMsg);
}
}
NodeHandle oldPredecessor = predecessorNode;
predecessorNode = joinResponse->getPreNode();
if (!oldPredecessor.isUnspecified()
&& !joinResponse->getPreNode().isUnspecified()
&& oldPredecessor != joinResponse->getPreNode()) {
callUpdate(oldPredecessor, false);
}
callUpdate(predecessorNode, true);
}
}
updateTooltip();
changeState(READY);
// immediate stabilization protocol
cancelEvent(stabilize_timer);
scheduleAt(simTime(), stabilize_timer);
// immediate finger repair protocol
cancelEvent(fixfingers_timer);
scheduleAt(simTime(), fixfingers_timer);
| void oversim::Chord::handleRpcNotifyResponse | ( | NotifyResponse * | notifyResponse | ) | [protected, virtual] |
Definition at line 1191 of file Chord.cc.
Referenced by handleRpcResponse().
{
if (state != READY) {
return;
}
if (successorList->getSuccessor() != notifyResponse->getSrcNode()) {
EV << "[Chord::handleRpcNotifyResponse() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " The srcNode of the received NotifyResponse is not our "
<< " current successor"
<< endl;
return;
}
// if the NotifyResponse sender couldn't accept me as predecessor,
// put its predecessor into the successor list and starts stabilizing
if (mergeOptimizationL3) {
if (!notifyResponse->getPreNodeSet()) {
StabilizeCall *call = new StabilizeCall("StabilizeCall");
call->setBitLength(STABILIZECALL_L(call));
successorList->addSuccessor(notifyResponse->getPreNode());
if (successorList->getSuccessor() == notifyResponse->getPreNode())
sendUdpRpcCall(notifyResponse->getPreNode(), call);
return;
}
}
// replace our successor list by our successor's successor list
successorList->updateList(notifyResponse);
updateTooltip();
| void oversim::Chord::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
| cPolymorphic * | context, | |||
| int | rpcId, | |||
| simtime_t | rtt | |||
| ) | [protected, virtual] |
Reimplemented in oversim::Koorde.
Definition at line 315 of file Chord.cc.
{
RPC_SWITCH_START(msg)
RPC_ON_RESPONSE( Join ) {
handleRpcJoinResponse(_JoinResponse);
EV << "[Chord::handleRpcResponse() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Received a Join RPC Response: id=" << rpcId << "\n"
<< " msg=" << *_JoinResponse << " rtt=" << rtt
<< endl;
break;
}
RPC_ON_RESPONSE( Notify ) {
handleRpcNotifyResponse(_NotifyResponse);
EV << "[Chord::handleRpcResponse() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Received a Notify RPC Response: id=" << rpcId << "\n"
<< " msg=" << *_NotifyResponse << " rtt=" << rtt
<< endl;
break;
}
RPC_ON_RESPONSE( Stabilize ) {
handleRpcStabilizeResponse(_StabilizeResponse);
EV << "[Chord::handleRpcResponse() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Received a Stabilize RPC Response: id=" << rpcId << "\n"
<< " msg=" << *_StabilizeResponse << " rtt=" << rtt
<< endl;
break;
}
RPC_ON_RESPONSE( Fixfingers ) {
handleRpcFixfingersResponse(_FixfingersResponse, SIMTIME_DBL(rtt));
EV << "[Chord::handleRpcResponse() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Received a Fixfingers RPC Response: id=" << rpcId << "\n"
<< " msg=" << *_FixfingersResponse << " rtt=" << rtt
<< endl;
break;
}
RPC_SWITCH_END( )
| void oversim::Chord::handleRpcStabilizeResponse | ( | StabilizeResponse * | stabilizeResponse | ) | [protected, virtual] |
Definition at line 1071 of file Chord.cc.
Referenced by handleRpcResponse().
{
if (state != READY) {
return;
}
// fetch the successor's predecessor
const NodeHandle& predecessor = stabilizeResponse->getPreNode();
// is the successor's predecessor a new successor for this node?
if ((successorList->isEmpty() ||
predecessor.getKey().isBetween(thisNode.getKey(),
successorList->getSuccessor().getKey())) &&
(failedSuccessor.isUnspecified() || failedSuccessor != predecessor)) {
if (successorList->isEmpty() && predecessor.isUnspecified()) {
// successor is emptry and the sender of the response has
// no predecessor => take the sender as new successor
successorList->addSuccessor(stabilizeResponse->getSrcNode());
} else {
// add the successor's predecessor to the successor list
successorList->addSuccessor(predecessor);
}
updateTooltip();
}
// compile NOTIFY RPC
NotifyCall* notifyCall = new NotifyCall("NotifyCall");
notifyCall->setBitLength(NOTIFYCALL_L(notifyCall));
notifyCall->setFailed(failedSuccessor);
failedSuccessor = TransportAddress::UNSPECIFIED_NODE;
sendUdpRpcCall(successorList->getSuccessor(), notifyCall);
| void oversim::Chord::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
| const TransportAddress & | dest, | |||
| cPolymorphic * | context, | |||
| int | rpcId, | |||
| const OverlayKey & | destKey | |||
| ) | [protected, virtual] |
Reimplemented in oversim::Koorde.
Definition at line 359 of file Chord.cc.
{
RPC_SWITCH_START(msg)
RPC_ON_CALL( FindNode ) {
EV << "[Chord::handleRpcTimeout() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " FindNode RPC Call timed out: id=" << rpcId << "\n"
<< " msg=" << *_FindNodeCall
<< endl;
break;
}
RPC_ON_CALL( Join ) {
EV << "[Chord::handleRpcTimeout() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Join RPC Call timed out: id=" << rpcId << "\n"
<< " msg=" << *_JoinCall
<< endl;
break;
}
RPC_ON_CALL( Notify ) {
EV << "[Chord::handleRpcTimeout() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Notify RPC Call timed out: id=" << rpcId << "\n"
<< " msg=" << *_NotifyCall
<< endl;
if (!handleFailedNode(dest)) join();
break;
}
RPC_ON_CALL( Stabilize ) {
EV << "[Chord::handleRpcTimeout() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Stabilize RPC Call timed out: id=" << rpcId << "\n"
<< " msg=" << *_StabilizeCall
<< endl;
if (!handleFailedNode(dest)) join();
break;
}
RPC_ON_CALL( Fixfingers ) {
EV << "[Chord::handleRpcTimeout() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Fixfingers RPC Call timed out: id=" << rpcId << "\n"
<< " msg=" << *_FixfingersCall
<< endl;
break;
}
RPC_SWITCH_END( )
| void oversim::Chord::handleStabilizeTimerExpired | ( | cMessage * | msg | ) | [protected, virtual] |
handle a expired stabilize timer
| msg | the timer self-message |
Definition at line 792 of file Chord.cc.
Referenced by handleTimerEvent().
{
if (state != READY)
return;
// alternative predecessor check
if ((checkPredecessorDelay == 0) &&
(missingPredecessorStabRequests >= stabilizeRetry)) {
// predecessor node seems to be dead
// remove it from the predecessor / successor lists
//successorList->removeSuccessor(predecessorNode);
predecessorNode = NodeHandle::UNSPECIFIED_NODE;
missingPredecessorStabRequests = 0;
updateTooltip();
callUpdate(predecessorNode, false);
}
if (!successorList->isEmpty()) {
// call STABILIZE RPC
StabilizeCall* call = new StabilizeCall("StabilizeCall");
call->setBitLength(STABILIZECALL_L(call));
sendUdpRpcCall(successorList->getSuccessor(), call);
missingPredecessorStabRequests++;
}
// check if fingers are still alive and remove unreachable finger nodes
if (mergeOptimizationL4) {
OverlayKey offset;
for (uint32_t nextFinger = 0; nextFinger < thisNode.getKey().getLength();
nextFinger++) {
offset = OverlayKey::pow2(nextFinger);
// send message only for non-trivial fingers
if (offset > successorList->getSuccessor().getKey() - thisNode.getKey()) {
if ((fingerTable->getFinger(nextFinger)).isUnspecified()) {
continue;
} else {
pingNode(fingerTable->getFinger(nextFinger), -1, 0, NULL,
NULL, NULL, nextFinger);
}
}
}
}
// schedule next stabilization process
cancelEvent(stabilize_timer);
scheduleAt(simTime() + stabilizeDelay, msg);
| void oversim::Chord::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
Reimplemented in oversim::Koorde.
Definition at line 248 of file Chord.cc.
{
// catch JOIN timer
if (msg == join_timer) {
handleJoinTimerExpired(msg);
}
// catch STABILIZE timer
else if (msg == stabilize_timer) {
handleStabilizeTimerExpired(msg);
}
// catch FIX_FINGERS timer
else if (msg == fixfingers_timer) {
handleFixFingersTimerExpired(msg);
}
// catch CHECK_PREDECESSOR timer
else if (msg == checkPredecessor_timer) {
cancelEvent(checkPredecessor_timer);
scheduleAt(simTime() + checkPredecessorDelay,
checkPredecessor_timer);
if (!predecessorNode.isUnspecified()) pingNode(predecessorNode);
}
// unknown self message
else {
error("Chord::handleTimerEvent(): received self message of "
"unknown type!");
}
| void oversim::Chord::handleUDPMessage | ( | BaseOverlayMessage * | msg | ) | [virtual] |
Reimplemented in oversim::Koorde.
Definition at line 277 of file Chord.cc.
{
ChordMessage* chordMsg = check_and_cast<ChordMessage*>(msg);
switch(chordMsg->getCommand()) {
case NEWSUCCESSORHINT:
handleNewSuccessorHint(chordMsg);
break;
default:
error("handleUDPMessage(): Unknown message type!");
break;
}
delete chordMsg;
| void oversim::Chord::initializeFriendModules | ( | ) | [protected, virtual] |
initializes finger table and successor list
Reimplemented in oversim::Koorde.
Definition at line 1368 of file Chord.cc.
Referenced by changeState().
{
// initialize finger table
fingerTable->initializeTable(thisNode.getKey().getLength(), thisNode, this);
// initialize successor list
successorList->initializeList(par("successorListSize"), thisNode, this);
| void oversim::Chord::initializeOverlay | ( | int | stage | ) | [virtual] |
Reimplemented in oversim::Koorde.
Definition at line 45 of file Chord.cc.
{
// because of IPAddressResolver, we need to wait until interfaces
// are registered, address auto-assignment takes place etc.
if (stage != MIN_STAGE_OVERLAY)
return;
if (iterativeLookupConfig.merge == true) {
throw cRuntimeError("Chord::initializeOverlay(): "
"Chord doesn't work with iterativeLookupConfig.merge = true!");
}
// Chord provides KBR services
kbr = true;
// fetch some parameters
useCommonAPIforward = par("useCommonAPIforward");
successorListSize = par("successorListSize");
joinRetry = par("joinRetry");
stabilizeRetry = par("stabilizeRetry");
joinDelay = par("joinDelay");
stabilizeDelay = par("stabilizeDelay");
fixfingersDelay = par("fixfingersDelay");
checkPredecessorDelay = par("checkPredecessorDelay");
aggressiveJoinMode = par("aggressiveJoinMode");
extendedFingerTable = par("extendedFingerTable");
numFingerCandidates = par("numFingerCandidates");
proximityRouting = par("proximityRouting");
memorizeFailedSuccessor = par("memorizeFailedSuccessor");
// merging optimizations
mergeOptimizationL1 = par("mergeOptimizationL1");
mergeOptimizationL2 = par("mergeOptimizationL2");
mergeOptimizationL3 = par("mergeOptimizationL3");
mergeOptimizationL4 = par("mergeOptimizationL4");
keyLength = OverlayKey::getLength();
missingPredecessorStabRequests = 0;
// statistics
joinCount = 0;
stabilizeCount = 0;
fixfingersCount = 0;
notifyCount = 0;
newsuccessorhintCount = 0;
joinBytesSent = 0;
stabilizeBytesSent = 0;
notifyBytesSent = 0;
fixfingersBytesSent = 0;
newsuccessorhintBytesSent = 0;
failedSuccessor = TransportAddress::UNSPECIFIED_NODE;
// find friend modules
findFriendModules();
// add some watches
WATCH(predecessorNode);
WATCH(thisNode);
WATCH(bootstrapNode);
WATCH(joinRetry);
WATCH(missingPredecessorStabRequests);
// self-messages
join_timer = new cMessage("join_timer");
stabilize_timer = new cMessage("stabilize_timer");
fixfingers_timer = new cMessage("fixfingers_timer");
checkPredecessor_timer = new cMessage("checkPredecessor_timer");
| bool oversim::Chord::isSiblingFor | ( | const NodeHandle & | node, | |
| const OverlayKey & | key, | |||
| int | numSiblings, | |||
| bool * | err | |||
| ) | [protected, virtual] |
Definition at line 421 of file Chord.cc.
Referenced by findNode().
{
if (key.isUnspecified())
error("Chord::isSiblingFor(): key is unspecified!");
if (state != READY) {
*err = true;
return false;
}
if (numSiblings > getMaxNumSiblings()) {
opp_error("Chord::isSiblingFor(): numSiblings too big!");
}
// set default number of siblings to consider
if (numSiblings == -1) numSiblings = getMaxNumSiblings();
// if this is the first and only node on the ring, it is responsible
if ((predecessorNode.isUnspecified()) && (node == thisNode)) {
if (successorList->isEmpty() || (node.getKey() == key)) {
*err = false;
return true;
} else {
*err = true;
return false;
}
}
if ((node == thisNode)
&& (key.isBetweenR(predecessorNode.getKey(), thisNode.getKey()))) {
*err = false;
return true;
}
NodeHandle prevNode = predecessorNode;
NodeHandle curNode;
for (int i = -1; i < (int)successorList->getSize();
i++, prevNode = curNode) {
if (i < 0) {
curNode = thisNode;
} else {
curNode = successorList->getSuccessor(i);
}
if (node == curNode) {
// is the message destined for curNode?
if (key.isBetweenR(prevNode.getKey(), curNode.getKey())) {
if (numSiblings <= ((int)successorList->getSize() - i)) {
*err = false;
return true;
} else {
*err = true;
return false;
}
} else {
// the key doesn't directly belong to this node, but
// the node could be a sibling for this key
if (numSiblings <= 1) {
*err = false;
return false;
} else {
// In Chord we don't know if we belong to the
// replicaSet of one of our predecessors
*err = true;
return false;
}
}
}
}
// node is not in our neighborSet
*err = true;
return false;
| void oversim::Chord::joinForeignPartition | ( | const NodeHandle & | node | ) | [protected, virtual] |
Definition at line 134 of file Chord.cc.
{
Enter_Method_Silent();
// create a join call and sent to the bootstrap node.
JoinCall *call = new JoinCall("JoinCall");
call->setBitLength(JOINCALL_L(call));
RoutingType routingType = (defaultRoutingType == FULL_RECURSIVE_ROUTING ||
defaultRoutingType == RECURSIVE_SOURCE_ROUTING) ?
SEMI_RECURSIVE_ROUTING : defaultRoutingType;
sendRouteRpcCall(OVERLAY_COMP, node, thisNode.getKey(),
call, NULL, routingType, joinDelay);
| void oversim::Chord::joinOverlay | ( | ) | [protected, virtual] |
Definition at line 127 of file Chord.cc.
{
changeState(INIT);
changeState(BOOTSTRAP);
| void oversim::Chord::pingResponse | ( | PingResponse * | pingResponse, | |
| cPolymorphic * | context, | |||
| int | rpcId, | |||
| simtime_t | rtt | |||
| ) | [protected, virtual] |
Definition at line 1333 of file Chord.cc.
{
EV << "[Chord::pingResponse() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Received a Ping RPC Response: id=" << rpcId << "\n"
<< " msg=" << *pingResponse << " rtt=" << rtt
<< endl;
if (rpcId != -1)
fingerTable->updateFinger(rpcId, pingResponse->getSrcNode(), rtt);
| void oversim::Chord::pingTimeout | ( | PingCall * | pingCall, | |
| const TransportAddress & | dest, | |||
| cPolymorphic * | context, | |||
| int | rpcId | |||
| ) | [protected, virtual] |
| void oversim::Chord::proxCallback | ( | const TransportAddress & | node, | |
| int | rpcId, | |||
| cPolymorphic * | contextPointer, | |||
| Prox | prox | |||
| ) | [virtual] |
Implements ProxListener.
Definition at line 1321 of file Chord.cc.
{
if (prox == Prox::PROX_TIMEOUT) {
// call join dependant on return value?
handleFailedNode(node);
return;
}
fingerTable->updateFinger(rpcId, (NodeHandle&)node, prox.proximity);
| void oversim::Chord::recordOverlaySentStats | ( | BaseOverlayMessage * | msg | ) | [virtual] |
Reimplemented in oversim::Koorde.
Definition at line 675 of file Chord.cc.
{
BaseOverlayMessage* innerMsg = msg;
while (innerMsg->getType() != APPDATA &&
innerMsg->getEncapsulatedPacket() != NULL) {
innerMsg =
static_cast<BaseOverlayMessage*>(innerMsg->getEncapsulatedPacket());
}
switch (innerMsg->getType()) {
case OVERLAYSIGNALING: {
ChordMessage* chordMsg = dynamic_cast<ChordMessage*>(innerMsg);
switch(chordMsg->getCommand()) {
case NEWSUCCESSORHINT:
RECORD_STATS(newsuccessorhintCount++;
newsuccessorhintBytesSent += msg->getByteLength());
break;
}
break;
}
case RPC: {
if ((dynamic_cast<StabilizeCall*>(innerMsg) != NULL) ||
(dynamic_cast<StabilizeResponse*>(innerMsg) != NULL)) {
RECORD_STATS(stabilizeCount++; stabilizeBytesSent +=
msg->getByteLength());
} else if ((dynamic_cast<NotifyCall*>(innerMsg) != NULL) ||
(dynamic_cast<NotifyResponse*>(innerMsg) != NULL)) {
RECORD_STATS(notifyCount++; notifyBytesSent +=
msg->getByteLength());
} else if ((dynamic_cast<FixfingersCall*>(innerMsg) != NULL) ||
(dynamic_cast<FixfingersResponse*>(innerMsg) != NULL)) {
RECORD_STATS(fixfingersCount++; fixfingersBytesSent +=
msg->getByteLength());
} else if ((dynamic_cast<JoinCall*>(innerMsg) != NULL) ||
(dynamic_cast<JoinResponse*>(innerMsg) != NULL)) {
RECORD_STATS(joinCount++; joinBytesSent += msg->getByteLength());
}
break;
}
case APPDATA:
break;
default:
throw cRuntimeError("Unknown message type!");
}
| void oversim::Chord::rpcFixfingers | ( | FixfingersCall * | call | ) | [protected] |
Fixfingers Remote-Procedure-Call.
| call | RPC Parameter Message |
Definition at line 1227 of file Chord.cc.
Referenced by handleRpcCall().
{
FixfingersResponse* fixfingersResponse =
new FixfingersResponse("FixfingersResponse");
fixfingersResponse->setSucNodeArraySize(1);
fixfingersResponse->setSucNode(0, thisNode);
if (extendedFingerTable) {
fixfingersResponse->setSucNodeArraySize(((successorList->getSize() + 1
< numFingerCandidates + 1)
? successorList->getSize() + 1
: numFingerCandidates + 1));
for (unsigned int i = 0;
i < (((successorList->getSize()) < numFingerCandidates)
? (successorList->getSize()) : numFingerCandidates); i++) {
assert(!successorList->getSuccessor(i).isUnspecified());
fixfingersResponse->setSucNode(i + 1,
successorList->getSuccessor(i));
}
}
fixfingersResponse->setFinger(call->getFinger());
fixfingersResponse->setBitLength(FIXFINGERSRESPONSE_L(fixfingersResponse));
sendRpcResponse(call, fixfingersResponse);
| void oversim::Chord::rpcJoin | ( | JoinCall * | call | ) | [protected, virtual] |
Join Remote-Procedure-Call.
| call | RPC Parameter Message |
Reimplemented in oversim::Koorde.
Definition at line 916 of file Chord.cc.
Referenced by handleRpcCall().
{
NodeHandle requestor = joinCall->getSrcNode();
// compile successor list
JoinResponse* joinResponse =
new JoinResponse("JoinResponse");
int sucNum = successorList->getSize();
joinResponse->setSucNum(sucNum);
joinResponse->setSucNodeArraySize(sucNum);
for (int k = 0; k < sucNum; k++) {
joinResponse->setSucNode(k, successorList->getSuccessor(k));
}
// sent our predecessor as hint to the joining node
if (predecessorNode.isUnspecified() && successorList->isEmpty()) {
// we are the only node in the ring
joinResponse->setPreNode(thisNode);
} else {
joinResponse->setPreNode(predecessorNode);
}
joinResponse->setBitLength(JOINRESPONSE_L(joinResponse));
sendRpcResponse(joinCall, joinResponse);
if (aggressiveJoinMode) {
// aggressiveJoinMode differs from standard join operations:
// 1. set our predecessor pointer to the joining node
// 2. send our old predecessor as hint in JoinResponse msgs
// 3. send a NEWSUCCESSORHINT to our old predecessor to update
// its successor pointer
// send NEWSUCCESSORHINT to our old predecessor
if (!predecessorNode.isUnspecified()) {
NewSuccessorHintMessage* newSuccessorHintMsg =
new NewSuccessorHintMessage("NEWSUCCESSORHINT");
newSuccessorHintMsg->setCommand(NEWSUCCESSORHINT);
newSuccessorHintMsg->setSrcNode(thisNode);
newSuccessorHintMsg->setPreNode(requestor);
newSuccessorHintMsg->
setBitLength(NEWSUCCESSORHINT_L(newSuccessorHintMsg));
sendMessageToUDP(predecessorNode, newSuccessorHintMsg);
}
if (predecessorNode.isUnspecified() || (predecessorNode != requestor)) {
// the requestor is our new predecessor
NodeHandle oldPredecessor = predecessorNode;
predecessorNode = requestor;
// send update to application if we've got a new predecessor
if (!oldPredecessor.isUnspecified()) {
callUpdate(oldPredecessor, false);
}
callUpdate(predecessorNode, true);
}
}
// if we don't have a successor, the requestor is also our new successor
if (successorList->isEmpty())
successorList->addSuccessor(requestor);
updateTooltip();
| void oversim::Chord::rpcNotify | ( | NotifyCall * | call | ) | [protected, virtual] |
NOTIFY Remote-Procedure-Call.
| call | RPC Parameter Message |
Definition at line 1105 of file Chord.cc.
Referenced by handleRpcCall().
{
// our predecessor seems to be alive
if (!predecessorNode.isUnspecified() &&
call->getSrcNode() == predecessorNode) {
missingPredecessorStabRequests = 0;
}
bool newPredecessorSet = false;
NodeHandle newPredecessor = call->getSrcNode();
// is the new predecessor closer than the current one?
if (predecessorNode.isUnspecified() ||
newPredecessor.getKey().isBetween(predecessorNode.getKey(), thisNode.getKey()) ||
(!call->getFailed().isUnspecified() &&
call->getFailed() == predecessorNode)) {
if ((predecessorNode.isUnspecified()) ||
(newPredecessor != predecessorNode)) {
// set up new predecessor
NodeHandle oldPredecessor = predecessorNode;
predecessorNode = newPredecessor;
if (successorList->isEmpty()) {
successorList->addSuccessor(newPredecessor);
}
newPredecessorSet = true;
updateTooltip();
// send update to application if we've got a new predecessor
if (!oldPredecessor.isUnspecified()) {
callUpdate(oldPredecessor, false);
}
callUpdate(predecessorNode, true);
// inform the original predecessor about the new predecessor
if (mergeOptimizationL1) {
if (!oldPredecessor.isUnspecified()) {
NewSuccessorHintMessage *newSuccessorHintMsg =
new NewSuccessorHintMessage("NEWSUCCESSORHINT");
newSuccessorHintMsg->setCommand(NEWSUCCESSORHINT);
newSuccessorHintMsg->setSrcNode(thisNode);
newSuccessorHintMsg->setPreNode(predecessorNode);
newSuccessorHintMsg->
setBitLength(NEWSUCCESSORHINT_L(newSuccessorHintMsg));
sendMessageToUDP(oldPredecessor, newSuccessorHintMsg);
}
}
}
}
// compile NOTIFY response
NotifyResponse* notifyResponse = new NotifyResponse("NotifyResponse");
int sucNum = successorList->getSize();
notifyResponse->setSucNum(sucNum);
notifyResponse->setSucNodeArraySize(sucNum);
// can't accept the notify sender as predecessor,
// tell it about my correct predecessor
if (mergeOptimizationL3) {
if (!newPredecessorSet && (predecessorNode != newPredecessor)) {
notifyResponse->setPreNode(predecessorNode);
notifyResponse->setPreNodeSet(false);
} else {
notifyResponse->setPreNodeSet(true);
}
}
for (int k = 0; k < sucNum; k++) {
notifyResponse->setSucNode(k, successorList->getSuccessor(k));
}
notifyResponse->setBitLength(NOTIFYRESPONSE_L(notifyResponse));
sendRpcResponse(call, notifyResponse);
| void oversim::Chord::rpcStabilize | ( | StabilizeCall * | call | ) | [protected] |
STABILIZE Remote-Procedure-Call.
| call | RPC Parameter Message |
Definition at line 1054 of file Chord.cc.
Referenced by handleRpcCall().
{
// our predecessor seems to be alive
if (!predecessorNode.isUnspecified() &&
call->getSrcNode() == predecessorNode) {
missingPredecessorStabRequests = 0;
}
// reply with StabilizeResponse message
StabilizeResponse* stabilizeResponse =
new StabilizeResponse("StabilizeResponse");
stabilizeResponse->setPreNode(predecessorNode);
stabilizeResponse->setBitLength(STABILIZERESPONSE_L(stabilizeResponse));
sendRpcResponse(call, stabilizeResponse);
| void oversim::Chord::updateTooltip | ( | ) | [virtual] |
updates information shown in tk-environment
Reimplemented in oversim::Koorde.
Definition at line 1378 of file Chord.cc.
Referenced by changeState(), handleFailedNode(), handleNewSuccessorHint(), handleRpcJoinResponse(), handleRpcNotifyResponse(), handleRpcStabilizeResponse(), handleStabilizeTimerExpired(), rpcJoin(), and rpcNotify().
{
if (ev.isGUI()) {
std::stringstream ttString;
// show our predecessor and successor in tooltip
ttString << predecessorNode << endl << thisNode << endl
<< successorList->getSuccessor();
getParentModule()->getParentModule()->getDisplayString().
setTagArg("tt", 0, ttString.str().c_str());
getParentModule()->getDisplayString().
setTagArg("tt", 0, ttString.str().c_str());
getDisplayString().setTagArg("tt", 0, ttString.str().c_str());
// draw an arrow to our current successor
showOverlayNeighborArrow(successorList->getSuccessor(), true,
"m=m,50,0,50,0;ls=red,1");
showOverlayNeighborArrow(predecessorNode, false,
"m=m,50,100,50,100;ls=green,1");
}
friend class ChordFingerTable [friend] |
friend class ChordSuccessorList [friend] |
bool oversim::Chord::aggressiveJoinMode [protected] |
use modified (faster) JOIN protocol
Definition at line 89 of file Chord.h.
Referenced by handleRpcJoinResponse(), initializeOverlay(), and rpcJoin().
TransportAddress oversim::Chord::bootstrapNode [protected] |
node used to bootstrap
Definition at line 131 of file Chord.h.
Referenced by changeState(), oversim::Koorde::handleDeBruijnTimerExpired(), handleJoinTimerExpired(), and initializeOverlay().
cMessage* oversim::Chord::checkPredecessor_timer [protected] |
Definition at line 105 of file Chord.h.
Referenced by changeState(), handleTimerEvent(), initializeOverlay(), and ~Chord().
double oversim::Chord::checkPredecessorDelay [protected] |
Definition at line 87 of file Chord.h.
Referenced by changeState(), handleStabilizeTimerExpired(), handleTimerEvent(), and initializeOverlay().
bool oversim::Chord::extendedFingerTable [protected] |
Definition at line 90 of file Chord.h.
Referenced by closestPreceedingNode(), getMaxNumRedundantNodes(), handleRpcFixfingersResponse(), initializeOverlay(), and rpcFixfingers().
Definition at line 274 of file Chord.h.
Referenced by handleFailedNode(), handleRpcStabilizeResponse(), and initializeOverlay().
ChordFingerTable* oversim::Chord::fingerTable [protected] |
pointer to this node's finger table
Definition at line 134 of file Chord.h.
Referenced by Chord(), closestPreceedingNode(), findFriendModules(), handleFailedNode(), handleFixFingersTimerExpired(), handleRpcFixfingersResponse(), handleStabilizeTimerExpired(), initializeFriendModules(), pingResponse(), and proxCallback().
cMessage* oversim::Chord::fixfingers_timer [protected] |
Definition at line 104 of file Chord.h.
Referenced by oversim::Koorde::changeState(), changeState(), Chord(), handleFailedNode(), handleFixFingersTimerExpired(), oversim::Koorde::handleRpcJoinResponse(), handleRpcJoinResponse(), handleTimerEvent(), initializeOverlay(), and ~Chord().
int oversim::Chord::fixfingersBytesSent [protected] |
Definition at line 116 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Chord::fixfingersCount [protected] |
Definition at line 110 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
double oversim::Chord::fixfingersDelay [protected] |
Definition at line 86 of file Chord.h.
Referenced by changeState(), handleFixFingersTimerExpired(), and initializeOverlay().
cMessage* oversim::Chord::join_timer [protected] |
Definition at line 102 of file Chord.h.
Referenced by oversim::Koorde::changeState(), changeState(), Chord(), handleJoinTimerExpired(), oversim::Koorde::handleRpcDeBruijnResponse(), handleTimerEvent(), initializeOverlay(), and ~Chord().
int oversim::Chord::joinBytesSent [protected] |
Definition at line 113 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Chord::joinCount [protected] |
Definition at line 108 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
double oversim::Chord::joinDelay [protected] |
Definition at line 84 of file Chord.h.
Referenced by handleJoinTimerExpired(), initializeOverlay(), and joinForeignPartition().
int oversim::Chord::joinRetry [protected] |
Definition at line 82 of file Chord.h.
Referenced by handleJoinTimerExpired(), and initializeOverlay().
int oversim::Chord::keyLength [protected] |
length of an overlay key in bits
Definition at line 119 of file Chord.h.
Referenced by initializeOverlay().
bool oversim::Chord::memorizeFailedSuccessor [protected] |
Definition at line 93 of file Chord.h.
Referenced by handleFailedNode(), and initializeOverlay().
bool oversim::Chord::mergeOptimizationL1 [protected] |
Definition at line 95 of file Chord.h.
Referenced by initializeOverlay(), and rpcNotify().
bool oversim::Chord::mergeOptimizationL2 [protected] |
Definition at line 96 of file Chord.h.
Referenced by handleRpcJoinResponse(), and initializeOverlay().
bool oversim::Chord::mergeOptimizationL3 [protected] |
Definition at line 97 of file Chord.h.
Referenced by handleNewSuccessorHint(), handleRpcNotifyResponse(), initializeOverlay(), and rpcNotify().
bool oversim::Chord::mergeOptimizationL4 [protected] |
Definition at line 98 of file Chord.h.
Referenced by handleStabilizeTimerExpired(), and initializeOverlay().
int oversim::Chord::missingPredecessorStabRequests [protected] |
missing StabilizeCall msgs
Definition at line 120 of file Chord.h.
Referenced by handleStabilizeTimerExpired(), initializeOverlay(), rpcNotify(), and rpcStabilize().
bool oversim::Chord::newChordFingerTable [protected] |
int oversim::Chord::newsuccessorhintBytesSent [protected] |
Definition at line 117 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Chord::newsuccessorhintCount [protected] |
Definition at line 112 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Chord::notifyBytesSent [protected] |
Definition at line 115 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Chord::notifyCount [protected] |
Definition at line 111 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
unsigned int oversim::Chord::numFingerCandidates [protected] |
Definition at line 91 of file Chord.h.
Referenced by closestPreceedingNode(), getMaxNumRedundantNodes(), initializeOverlay(), and rpcFixfingers().
NodeHandle oversim::Chord::predecessorNode [protected] |
predecessor of this node
Definition at line 130 of file Chord.h.
Referenced by changeState(), closestPreceedingNode(), oversim::Koorde::findNode(), findNode(), oversim::Koorde::handleDeBruijnTimerExpired(), handleFailedNode(), oversim::Koorde::handleRpcDeBruijnRequest(), handleRpcJoinResponse(), handleStabilizeTimerExpired(), handleTimerEvent(), initializeOverlay(), isSiblingFor(), oversim::Koorde::rpcJoin(), rpcJoin(), rpcNotify(), rpcStabilize(), oversim::Koorde::updateTooltip(), and updateTooltip().
bool oversim::Chord::proximityRouting [protected] |
Definition at line 92 of file Chord.h.
Referenced by handleRpcFixfingersResponse(), and initializeOverlay().
cMessage* oversim::Chord::stabilize_timer [protected] |
Definition at line 103 of file Chord.h.
Referenced by changeState(), Chord(), handleFailedNode(), handleRpcJoinResponse(), handleStabilizeTimerExpired(), handleTimerEvent(), initializeOverlay(), and ~Chord().
int oversim::Chord::stabilizeBytesSent [protected] |
Definition at line 114 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Chord::stabilizeCount [protected] |
Definition at line 109 of file Chord.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
double oversim::Chord::stabilizeDelay [protected] |
stabilize interval (secs)
Definition at line 85 of file Chord.h.
Referenced by changeState(), handleStabilizeTimerExpired(), and initializeOverlay().
int oversim::Chord::stabilizeRetry [protected] |
// retries before neighbor considered failed
Definition at line 83 of file Chord.h.
Referenced by handleStabilizeTimerExpired(), and initializeOverlay().
ChordSuccessorList* oversim::Chord::successorList [protected] |
pointer to this node's successor list
Definition at line 135 of file Chord.h.
Referenced by closestPreceedingNode(), oversim::Koorde::findDeBruijnHop(), oversim::Koorde::findFriendModules(), findFriendModules(), oversim::Koorde::findNode(), findNode(), oversim::ChordFingerTable::getFinger(), oversim::Koorde::handleDeBruijnTimerExpired(), handleFailedNode(), handleFixFingersTimerExpired(), handleNewSuccessorHint(), oversim::Koorde::handleRpcDeBruijnRequest(), handleRpcJoinResponse(), handleRpcNotifyResponse(), handleRpcStabilizeResponse(), handleStabilizeTimerExpired(), oversim::Koorde::initializeFriendModules(), initializeFriendModules(), isSiblingFor(), rpcFixfingers(), oversim::Koorde::rpcJoin(), rpcJoin(), rpcNotify(), oversim::Koorde::updateTooltip(), updateTooltip(), and oversim::Koorde::walkSuccessorList().
int oversim::Chord::successorListSize [protected] |
Definition at line 88 of file Chord.h.
Referenced by getMaxNumSiblings(), handleRpcJoinResponse(), and initializeOverlay().
1.7.1