OverSim
oversim::Chord Class Reference

Chord overlay module. More...

#include <Chord.h>

Inheritance diagram for oversim::Chord:
BaseOverlay ProxListener BaseRpc BaseTcpSupport TopologyVis RpcListener oversim::Koorde

Public Member Functions

 Chord ()
virtual ~Chord ()
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void handleTimerEvent (cMessage *msg)
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
OverlayKey distance (const OverlayKey &x, const OverlayKey &y, bool useAlternative=false) const
 This method should implement the distance between two keys.
virtual void updateTooltip ()
 updates information shown in tk-environment
void proxCallback (const TransportAddress &node, int rpcId, cPolymorphic *contextPointer, Prox prox)
- Public Member Functions inherited from BaseOverlay
 BaseOverlay ()
virtual ~BaseOverlay ()
 Virtual destructor.
States getState ()
bool isMalicious ()
 Returns true, if node is malicious.
bool isInSimpleMultiOverlayHost ()
 Returns true if overlay is one in an array, inside a SimpleMultiOverlayHost.
const simtime_t & getCreationTime ()
void join (const OverlayKey &nodeID=OverlayKey::UNSPECIFIED_KEY)
 Join the overlay with a given nodeID.
virtual NodeVectorlocal_lookup (const OverlayKey &key, int num, bool safe)
 finds nodes closest to the given OverlayKey
virtual NodeVectorneighborSet (int num)
void sendMessageToUDP (const TransportAddress &dest, cPacket *msg, simtime_t delay=SIMTIME_ZERO)
 Sends message to underlay.
void sendToKey (const OverlayKey &key, BaseOverlayMessage *message, int numSiblings=1, const std::vector< TransportAddress > &sourceRoute=TransportAddress::UNSPECIFIED_NODES, RoutingType routingType=DEFAULT_ROUTING)
 Sends a message to an overlay node, with the generic routing algorithm.
void registerComp (CompType compType, cModule *module)
cModule * getCompModule (CompType compType)
cGate * getCompRpcGate (CompType compType)
void sendMessageToAllComp (cMessage *msg, CompType srcComp)
bool providesKbr ()
virtual uint8_t getBitsPerDigit ()
bool getMeasureAuthBlock ()
BootstrapListgetBootstrapList () const
virtual OverlayKey estimateMeanDistance ()
 returns mean distance between OverlayKeys in the network
virtual uint32_t estimateOverlaySize ()
 estimates the current number of nodes online
- Public Member Functions inherited from BaseRpc
 BaseRpc ()
const NodeHandlegetThisNode ()
 Returns the NodeHandle of this node.
simtime_t getUdpTimeout ()
- Public Member Functions inherited from RpcListener
virtual ~RpcListener ()
 destructor
- Public Member Functions inherited from BaseTcpSupport
virtual void socketDataArrived (int connId, void *yourPtr, cPacket *msg, bool urgent)
virtual void socketEstablished (int connId, void *yourPtr)
virtual void socketPeerClosed (int connId, void *yourPtr)
virtual void socketFailure (int connId, void *yourPtr, int code)
virtual void socketStatusArrived (int connId, void *yourPtr, TCPStatusInfo *status)
- Public Member Functions inherited from TopologyVis
 TopologyVis ()
void showOverlayNeighborArrow (const NodeHandle &neighbor, bool flush=true, const char *displayString=NULL)
 Draws an arrow from this node to neighbor.
void deleteOverlayNeighborArrow (const NodeHandle &neighbor)
 Removes an arrow from this node to neighbor.

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 NodeVectorclosestPreceedingNode (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)
 Processes Remote-Procedure-Call invocation messages.
NodeVectorfindNode (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 void joinForeignPartition (const NodeHandle &node)
 Join another overlay partition with the given node as bootstrap node.
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.
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)
 This method is called if an RPC response has been received.
virtual void handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey)
 This method is called if an RPC timeout has been reached.
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)
 Handles a failed node.
- Protected Member Functions inherited from BaseOverlay
int numInitStages () const
 Sets init stage.
void bindToPort (int port)
 Tells UDP we want to get all packets arriving on the given port.
virtual void route (const OverlayKey &key, CompType destComp, CompType srcComp, cPacket *msg, const std::vector< TransportAddress > &sourceRoute=TransportAddress::UNSPECIFIED_NODES, RoutingType routingType=DEFAULT_ROUTING)
 Routes message through overlay.
void callDeliver (BaseOverlayMessage *msg, const OverlayKey &destKey)
 Calls deliver function in application.
void callForward (const OverlayKey &key, BaseRouteMessage *msg, const NodeHandle &nextHopNode)
 Calls forward function in application.
void callUpdate (const NodeHandle &node, bool joined)
 Informs application about state changes of nodes or newly joined nodes.
void handleMessage (cMessage *msg)
 Checks for message type and calls corresponding method.
void handleBaseOverlayMessage (BaseOverlayMessage *msg, const OverlayKey &destKey=OverlayKey::UNSPECIFIED_KEY)
 Handles a BaseOverlayMessage

virtual void handleAppMessage (cMessage *msg)
 Processes "timer" self-messages.
virtual void receiveChangeNotification (int category, const cPolymorphic *details)
 callback-method for events at the NotificationBoard
virtual void handleTransportAddressChangedNotification ()
 This method gets call if the node has a new TransportAddress (IP address) because he changed his access network.
virtual void handleNodeLeaveNotification ()
 This method gets call **.gracefulLeaveDelay seconds before it is killed.
virtual void handleNodeGracefulLeaveNotification ()
 This method gets call **.gracefulLeaveDelay seconds before it is killed if this node is among the gracefulLeaveProbability nodes.
void setOverlayReady (bool ready)
 Sets the overlay ready icon and register/deregisters the node at the GlobalNodeList.
virtual AbstractLookupcreateLookup (RoutingType routingType=DEFAULT_ROUTING, const BaseOverlayMessage *msg=NULL, const cPacket *findNodeExt=NULL, bool appLookup=false)
 Creates an abstract iterative lookup instance.
virtual void removeLookup (AbstractLookup *lookup)
 Removes the abstract lookup instance.
virtual void lookupRpc (LookupCall *call)
virtual void nextHopRpc (NextHopCall *call)
void countFindNodeCall (const FindNodeCall *call)
void countFailedNodeCall (const FailedNodeCall *call)
bool internalHandleRpcCall (BaseCallMessage *msg)
 Handles internal rpc requests.
void internalHandleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt)
 Handles rpc responses internal in base classes

void internalHandleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey)
 Handles rpc timeouts internal in base classes

void internalSendRouteRpc (BaseRpcMessage *message, const OverlayKey &destKey, const std::vector< TransportAddress > &sourceRoute, RoutingType routingType)
CompType getThisCompType ()
 Return the component type of this module.
- Protected Member Functions inherited from BaseRpc
void initRpcs ()
 Initializes Remote-Procedure state.
void finishRpcs ()
 Deinitializes Remote-Procedure state.
virtual void internalHandleRpcMessage (BaseRpcMessage *msg)
 Handles incoming rpc messages and delegates them to the corresponding listeners or handlers.
uint32_t sendRouteRpcCall (CompType destComp, const TransportAddress &dest, const OverlayKey &destKey, BaseCallMessage *msg, cPolymorphic *context=NULL, RoutingType routingType=DEFAULT_ROUTING, simtime_t timeout=-1, int retries=0, int rpcId=-1, RpcListener *rpcListener=NULL)
 Routes a Remote-Procedure-Call message to an OverlayKey.
uint32_t sendRouteRpcCall (CompType destComp, const OverlayKey &destKey, BaseCallMessage *msg, cPolymorphic *context=NULL, RoutingType routingType=DEFAULT_ROUTING, simtime_t timeout=-1, int retries=0, int rpcId=-1, RpcListener *rpcListener=NULL)
 Routes a Remote-Procedure-Call message to an OverlayKey.
uint32_t sendRouteRpcCall (CompType destComp, const TransportAddress &dest, BaseCallMessage *msg, cPolymorphic *context=NULL, RoutingType routingType=DEFAULT_ROUTING, simtime_t timeout=-1, int retries=0, int rpcId=-1, RpcListener *rpcListener=NULL)
 Sends a Remote-Procedure-Call message using the overlay's UDP port
This replaces ROUTE_DIRECT calls!
uint32_t sendUdpRpcCall (const TransportAddress &dest, BaseCallMessage *msg, cPolymorphic *context=NULL, simtime_t timeout=-1, int retries=0, int rpcId=-1, RpcListener *rpcListener=NULL)
 Sends a Remote-Procedure-Call message to the underlay

uint32_t sendInternalRpcCall (CompType destComp, BaseCallMessage *msg, cPolymorphic *context=NULL, simtime_t timeout=-1, int retries=0, int rpcId=-1, RpcListener *rpcListener=NULL)
 Sends an internal Remote-Procedure-Call between two tiers

void cancelRpcMessage (uint32_t nonce)
 Cancels a Remote-Procedure-Call.
void cancelAllRpcs ()
 Cancels all RPCs.
void sendRpcResponse (TransportType transportType, CompType destComp, const TransportAddress &dest, const OverlayKey &destKey, BaseCallMessage *call, BaseResponseMessage *response)
 Send Remote-Procedure response message and deletes call message.
void sendRpcResponse (BaseCallMessage *call, BaseResponseMessage *response)
 Send Remote-Procedure response message to UDP and deletes call message.
int pingNode (const TransportAddress &dest, simtime_t timeout=-1, int retries=0, cPolymorphic *context=NULL, const char *caption="PING", RpcListener *rpcListener=NULL, int rpcId=-1, TransportType transportType=INVALID_TRANSPORT)
 ping a node by its TransportAddress
bool internalHandleMessage (cMessage *msg)
- Protected Member Functions inherited from RpcListener
virtual void handleRpcResponse (BaseResponseMessage *msg, const RpcState &rpcState, simtime_t rtt)
 This method is called if an RPC response has been received.
virtual void handleRpcTimeout (const RpcState &rpcState)
 This method is called if an RPC timeout has been reached.
- Protected Member Functions inherited from BaseTcpSupport
void handleTCPMessage (cMessage *msg)
 Member function to handle incoming TCP messages.
void bindAndListenTcp (int port)
 Member function to bind service to the specified port and listen afterwards.
bool isAlreadyConnected (TransportAddress address)
 Member function to check if the service is already connected.
void establishTcpConnection (TransportAddress address)
 Member function to establish a connection to the specified node.
void sendTcpData (cPacket *msg, TransportAddress address)
 Member function to send TCP data to the specified node.
virtual void handleConnectionEvent (EvCode code, TransportAddress address)
 Member function to handle passive connection events.
virtual void handleDataReceived (TransportAddress address, cPacket *msg, bool urgent)
 Member function to handle incoming data.
virtual void handleIncomingConnection (TransportAddress address)
 Member function to handle newly opened connections.
void closeTcpConnection (TransportAddress address)
 Member function to close an established connection.
void setTcpOut (cGate *gate)
 Member function to set local gate towards the TCP module during init phase.
cGate * getTcpOut ()
 Member function to get local gate towards the TCP module.
- Protected Member Functions inherited from TopologyVis
void initVis (cModule *terminal)

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
ChordFingerTablefingerTable
 pointer to this node's finger table
ChordSuccessorListsuccessorList
 pointer to this node's successor list
- Protected Attributes inherited from BaseOverlay
int numAppDataForwarded
 number of forwarded app data packets
int bytesAppDataForwarded
 number of forwarded app data bytes at out-gate
int numAppLookupForwarded
 number of forwarded app lookup packets
int bytesAppLookupForwarded
 number of forwarded app lookup bytes at out-gate
int numMaintenanceForwarded
 number of forwarded maintenance packets
int bytesMaintenanceForwarded
 number of forwarded maintenance bytes at out-gate
int numFindNodeSent
int bytesFindNodeSent
int numFindNodeResponseSent
int bytesFindNodeResponseSent
int numFailedNodeSent
int bytesFailedNodeSent
int numFailedNodeResponseSent
int bytesFailedNodeResponseSent
std::vector< HopDelayRecord * > singleHopDelays
simtime_t creationTime
 simtime when the node has been created
GlobalNodeListglobalNodeList
 pointer to GlobalNodeList in this node
NotificationBoard * notificationBoard
 pointer to NotificationBoard in this node
UnderlayConfiguratorunderlayConfigurator
 pointer to UnderlayConfigurator in this node
BootstrapListbootstrapList
 pointer to the BootstrapList module
GlobalParametersglobalParameters
 pointer to the GlobalParameters module
uint32_t overlayId
 identifies the overlay this node belongs to (used for multiple overlays)
bool debugOutput
 debug output ?
RoutingType defaultRoutingType
bool useCommonAPIforward
 forward messages to applications?
bool collectPerHopDelay
 collect delay for single hops
bool routeMsgAcks
 send ACK when receiving route message
uint32_t recNumRedundantNodes
 numRedundantNodes for recursive routing
bool recordRoute
 record visited hops on route
bool drawOverlayTopology
bool rejoinOnFailure
bool sendRpcResponseToLastHop
 needed by KBR protocols for NAT support
bool dropFindNodeAttack
 if node is malicious, it tries a findNode attack
bool isSiblingAttack
 if node is malicious, it tries a isSibling attack
bool invalidNodesAttack
 if node is malicious, it tries a invalidNode attack
bool dropRouteMessageAttack
 if node is malicious, it drops all received BaseRouteMessages
int localPort
 used UDP-port
int hopCountMax
 maximum hop count
bool measureAuthBlock
 if true, measure the overhead of signatures in rpc messages
bool restoreContext
 if true, a node rejoins with its old nodeId and malicious state
int numDropped
 number of dropped packets
int bytesDropped
 number of dropped bytes
cOutVector delayVector
 statistical output vector for packet-delays
cOutVector hopCountVector
 statistical output vector for hop-counts
States state
IterativeLookupConfiguration iterativeLookupConfig
RecursiveLookupConfiguration recursiveLookupConfig
LookupSet lookups
bool kbr
 set this to true, if the overlay provides KBR services
- Protected Attributes inherited from BaseRpc
NodeHandle thisNode
 NodeHandle to this node.
BaseOverlayoverlay
bool debugOutput
 debug output ?
GlobalStatisticsglobalStatistics
 pointer to GlobalStatistics module in this node
CompType thisCompType
NeighborCacheneighborCache
 pointer to the neighbor cache
CryptoModulecryptoModule
 pointer to CryptoModule
int numPingSent
int bytesPingSent
int numPingResponseSent
int bytesPingResponseSent
- Protected Attributes inherited from TopologyVis
cModule * thisTerminal
GlobalNodeListglobalNodeList
 pointer to corresponding node

Private Attributes

TransportAddress failedSuccessor

Friends

class ChordSuccessorList
class ChordFingerTable

Additional Inherited Members

- Public Types inherited from BaseOverlay
enum  States {
  INIT = 0, BOOTSTRAP = 1, DISCOVERY = 2, PREJOIN = 3,
  JOIN = 4, POSTJOIN = 5, READY = 6, REFRESH = 7,
  SHUTDOWN = 8, FAILED = 9, RSET = JOIN, BSET = POSTJOIN
}
- Protected Types inherited from BaseOverlay
typedef UNORDERED_SET
< AbstractLookup
*, lookupHashFcn,
lookupHashFcn
LookupSet

Detailed Description

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.

Author
Markus Mauch, Ingmar Baumgart
See Also
BaseOverlay, ChordFingerTable, ChordSuccessorList

Definition at line 47 of file Chord.h.

Constructor & Destructor Documentation

oversim::Chord::Chord ( )

Definition at line 41 of file Chord.cc.

oversim::Chord::~Chord ( )
virtual

Definition at line 119 of file Chord.cc.

{
// destroy self timer messages
cancelAndDelete(join_timer);
cancelAndDelete(stabilize_timer);
cancelAndDelete(fixfingers_timer);
cancelAndDelete(checkPredecessor_timer);
}

Member Function Documentation

void oversim::Chord::changeState ( int  toState)
protectedvirtual

changes node state

Parameters
toStatestate to change to

Reimplemented in oversim::Koorde.

Definition at line 154 of file Chord.cc.

{
//
// Defines tasks to be executed when a state change occurs.
//
switch (toState) {
case INIT:
// initialize predecessor pointer
// initialize finger table and successor list
// 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 JOIN:
// initiate join 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 JOIN stage"
<< endl;
}
getParentModule()->getParentModule()->bubble("Enter JOIN state.");
// find a new bootstrap node and enroll to the bootstrap list
// is this the first node?
// create new cord ring
}
break;
case READY:
// initiate stabilization protocol
cancelEvent(stabilize_timer);
scheduleAt(simTime() + stabilizeDelay, stabilize_timer);
// initiate finger repair protocol
cancelEvent(fixfingers_timer);
scheduleAt(simTime() + fixfingersDelay,
// initiate predecessor check
cancelEvent(checkPredecessor_timer);
scheduleAt(simTime() + checkPredecessorDelay,
}
// 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)
protectedvirtual

looks up the finger table and returns the closest preceeding node.

Parameters
keykey to find the closest preceeding node for
Returns
node vector of the closest preceeding nodes to key

Definition at line 604 of file Chord.cc.

{
// 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
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)) {
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--) {
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
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
virtual

This method should implement the distance between two keys.

It may be overloaded to implement a new metric. The default implementation uses the standard-metric d = abs(x-y).

Parameters
xLeft-hand-side Key
yRight-hand-side key
useAlternativeuse an alternative distance metric
Returns
OverlayKey Distance between x and y

Reimplemented from BaseOverlay.

Definition at line 1406 of file Chord.cc.

{
return KeyCwRingMetric().distance(x, y);
}
void oversim::Chord::findFriendModules ( )
protectedvirtual

Assigns the finger table and successor list module to our reference.

Reimplemented in oversim::Koorde.

Definition at line 1362 of file Chord.cc.

{
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 
)
protectedvirtual

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.

Parameters
keyThe lookup key.
numRedundantNodesMaximum number of next hop nodes to return.
numSiblingsnumber of siblings to return
msgA pointer to the BaseRouteMessage or FindNodeCall message of this lookup.
Returns
NodeVector with closest nodes.

Reimplemented from BaseOverlay.

Reimplemented in oversim::Koorde.

Definition at line 550 of file Chord.cc.

{
bool err;
NodeVector* nextHop;
if (state != READY)
return new NodeVector();
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(),
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

collects statistical data in derived class

Reimplemented from BaseOverlay.

Reimplemented in oversim::Koorde.

Definition at line 728 of file Chord.cc.

{
// remove this node from the bootstrap list
if (time < GlobalStatistics::MIN_MEASURED) return;
globalStatistics->addStdDev("Chord: Sent JOIN Messages/s",
joinCount / time);
globalStatistics->addStdDev("Chord: Sent NEWSUCCESSORHINT Messages/s",
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",
globalStatistics->addStdDev("Chord: Sent STABILIZE Bytes/s",
globalStatistics->addStdDev("Chord: Sent NOTIFY Bytes/s",
notifyBytesSent / time);
globalStatistics->addStdDev("Chord: Sent FIX_FINGERS Bytes/s",
}
int oversim::Chord::getMaxNumRedundantNodes ( )
protectedvirtual

Query the maximum number of redundant next hop nodes that are returned by findNode().

Returns
int number of redundant nodes returned by findNode().

Reimplemented from BaseOverlay.

Definition at line 418 of file Chord.cc.

int oversim::Chord::getMaxNumSiblings ( )
protectedvirtual

Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.

Returns
int number of siblings.

Reimplemented from BaseOverlay.

Definition at line 413 of file Chord.cc.

{
}
bool oversim::Chord::handleFailedNode ( const TransportAddress failed)
protectedvirtual

Handles a failed node.

This method is called whenever a node given by findNode() was unreachable. The default implementation does nothing at all.

Parameters
failedthe failed node
Returns
true if lookup should retry here

Reimplemented from BaseOverlay.

Reimplemented in oversim::Koorde.

Definition at line 504 of file Chord.cc.

{
Enter_Method_Silent();
//TODO const reference -> trying to compare unspec NH
// check pointer for koorde
if (fingerTable != NULL)
// 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
oldSuccessor == predecessorNode) {
}
if (failed == oldSuccessor) {
// schedule next stabilization process
failedSuccessor = oldSuccessor;
}
cancelEvent(stabilize_timer);
scheduleAt(simTime(), stabilize_timer);
}
if (state != READY) return true;
// 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)
protectedvirtual

handle a expired fix_fingers timer

Parameters
msgthe timer self-message

Definition at line 847 of file Chord.cc.

{
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,
} 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)
protectedvirtual

handle a expired join timer

Parameters
msgthe timer self-message

Definition at line 760 of file Chord.cc.

{
// only process timer, if node is not joined yet
if (state == READY)
return;
// enter state JOIN
if (state != JOIN)
// change bootstrap node from time to time
if (joinRetry == 0) {
joinRetry = par("joinRetry");
return;
}
// call JOIN RPC
JoinCall* call = new JoinCall("JoinCall");
call->setBitLength(JOINCALL_L(call));
call, NULL, routingType, joinDelay);
// schedule next join process in the case this one fails
cancelEvent(join_timer);
scheduleAt(simTime() + joinDelay, msg);
}
void oversim::Chord::handleNewSuccessorHint ( ChordMessage chordMsg)
protectedvirtual

handle a received NEWSUCCESSORHINT message

Parameters
chordMsgthe message to process

Definition at line 880 of file Chord.cc.

{
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(),
// add the successor's predecessor to the successor list
successorList->addSuccessor(predecessor);
}
// if the successor node reports a new successor, put it into the
// successor list and start stabilizing
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)
protectedvirtual

Processes Remote-Procedure-Call invocation messages.


This method should be overloaded when the overlay provides RPC functionality.

Returns
true, if rpc has been handled

Reimplemented from BaseRpc.

Reimplemented in oversim::Koorde.

Definition at line 296 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_DELEGATE( <messageName>[Call|Response], <methodToCall> )
RPC_DELEGATE( Notify, rpcNotify );
RPC_DELEGATE( Stabilize, rpcStabilize );
RPC_DELEGATE( Fixfingers, rpcFixfingers );
return RPC_HANDLED;
}
void oversim::Chord::handleRpcFixfingersResponse ( FixfingersResponse fixfingersResponse,
double  rtt = -1 
)
protectedvirtual

Definition at line 1259 of file Chord.cc.

{
/*
OverlayCtrlInfo* ctrlInfo =
check_and_cast<OverlayCtrlInfo*>(fixfingersResponse->getControlInfo());
RECORD_STATS(globalStatistics->recordOutVector("Chord: FIX_FINGERS response Hop Count", ctrlInfo->getHopCount()));
*/
// set new finger pointer#
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
#else
#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),
fixfingersResponse->getFinger(),
this, NULL);
if (prox == Prox::PROX_TIMEOUT) {
fingerTable->removeFinger(fixfingersResponse->getFinger());
} else if (prox != Prox::PROX_UNKNOWN &&
prox != Prox::PROX_WAITING &&
prox != Prox::PROX_SELF) {
fingerTable->updateFinger(fixfingersResponse->getFinger(),
fixfingersResponse->getSucNode(i),
prox.proximity);
}
}
}
}
}
void oversim::Chord::handleRpcJoinResponse ( JoinResponse joinResponse)
protectedvirtual

Reimplemented in oversim::Koorde.

Definition at line 990 of file Chord.cc.

{
// 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);
}
// the sender of this message is our new successor
// in aggressiveJoinMode: use hint in JoinResponse
// to set our new predecessor
// it is possible that the joinResponse doesn't contain a valid
// predecessor especially when merging two partitions
if (!joinResponse->getPreNode().isUnspecified()) {
// inform the original predecessor about the new predecessor
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);
}
}
}
// 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)
protectedvirtual

Definition at line 1194 of file Chord.cc.

{
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 (!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);
}
void oversim::Chord::handleRpcResponse ( BaseResponseMessage msg,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
)
protectedvirtual

This method is called if an RPC response has been received.

Parameters
msgThe response message.
contextPointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code
rpcIdThe RPC id.
rttThe Round-Trip-Time of this RPC

Reimplemented from RpcListener.

Reimplemented in oversim::Koorde.

Definition at line 318 of file Chord.cc.

{
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;
}
}
void oversim::Chord::handleRpcStabilizeResponse ( StabilizeResponse stabilizeResponse)
protectedvirtual

Definition at line 1074 of file Chord.cc.

{
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?
predecessor.getKey().isBetween(thisNode.getKey(),
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);
}
}
// compile NOTIFY RPC
NotifyCall* notifyCall = new NotifyCall("NotifyCall");
notifyCall->setBitLength(NOTIFYCALL_L(notifyCall));
notifyCall->setFailed(failedSuccessor);
}
void oversim::Chord::handleRpcTimeout ( BaseCallMessage msg,
const TransportAddress dest,
cPolymorphic *  context,
int  rpcId,
const OverlayKey destKey 
)
protectedvirtual

This method is called if an RPC timeout has been reached.

Parameters
msgThe original RPC message.
destThe destination node
contextPointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code
rpcIdThe RPC id.
destKeythe destination OverlayKey

Reimplemented from RpcListener.

Reimplemented in oversim::Koorde.

Definition at line 362 of file Chord.cc.

{
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;
}
}
void oversim::Chord::handleStabilizeTimerExpired ( cMessage *  msg)
protectedvirtual

handle a expired stabilize timer

Parameters
msgthe timer self-message

Definition at line 795 of file Chord.cc.

{
if (state != READY)
return;
// alternative predecessor check
if ((checkPredecessorDelay == 0) &&
// predecessor node seems to be dead
// remove it from the predecessor / successor lists
//successorList->removeSuccessor(predecessorNode);
}
// call STABILIZE RPC
StabilizeCall* call = new StabilizeCall("StabilizeCall");
call->setBitLength(STABILIZECALL_L(call));
}
// check if fingers are still alive and remove unreachable finger nodes
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 from BaseRpc.

Reimplemented in oversim::Koorde.

Definition at line 251 of file Chord.cc.

{
// catch JOIN timer
if (msg == join_timer) {
}
// catch STABILIZE timer
else if (msg == stabilize_timer) {
}
// catch FIX_FINGERS timer
else if (msg == fixfingers_timer) {
}
// catch CHECK_PREDECESSOR timer
else if (msg == checkPredecessor_timer) {
cancelEvent(checkPredecessor_timer);
scheduleAt(simTime() + checkPredecessorDelay,
}
// unknown self message
else {
error("Chord::handleTimerEvent(): received self message of "
"unknown type!");
}
}
void oversim::Chord::handleUDPMessage ( BaseOverlayMessage msg)
virtual

Processes messages from underlay.

Parameters
msgMessage from UDP

Reimplemented from BaseOverlay.

Reimplemented in oversim::Koorde.

Definition at line 280 of file Chord.cc.

{
ChordMessage* chordMsg = check_and_cast<ChordMessage*>(msg);
switch(chordMsg->getCommand()) {
break;
default:
error("handleUDPMessage(): Unknown message type!");
break;
}
delete chordMsg;
}
void oversim::Chord::initializeFriendModules ( )
protectedvirtual

initializes finger table and successor list

Reimplemented in oversim::Koorde.

Definition at line 1372 of file Chord.cc.

{
// initialize finger table
// initialize successor list
successorList->initializeList(par("successorListSize"), thisNode, this);
}
void oversim::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.

Parameters
stagethe init stage

Reimplemented from BaseOverlay.

Reimplemented in oversim::Koorde.

Definition at line 48 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;
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");
// statistics
joinCount = 0;
// find friend modules
// add some watches
WATCH(thisNode);
WATCH(bootstrapNode);
WATCH(joinRetry);
// 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 
)
protectedvirtual

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.

Parameters
nodethe NodeHandle
keydestination key
numSiblingsThe nodes knows all numSiblings nodes close to this key
errreturn false if the range could not be determined
Returns
bool true, if the node is responsible for the key.

Reimplemented from BaseOverlay.

Definition at line 424 of file Chord.cc.

{
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)
*err = false;
return true;
}
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)
protectedvirtual

Join another overlay partition with the given node as bootstrap node.

Join another overlay partition with the given node as bootstrap node. This method is called to join a foreign overlay partition and start the merging process.

Parameters
nodeThe foreign bootstrap node

Reimplemented from BaseOverlay.

Definition at line 137 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));
call, NULL, routingType, joinDelay);
}
void oversim::Chord::joinOverlay ( )
protectedvirtual

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.

Definition at line 130 of file Chord.cc.

void oversim::Chord::pingResponse ( PingResponse pingResponse,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
)
protectedvirtual

Reimplemented from BaseRpc.

Definition at line 1337 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 
)
protectedvirtual

Reimplemented from BaseRpc.

Definition at line 1350 of file Chord.cc.

{
EV << "[Chord::pingTimeout() @ " << thisNode.getIp()
<< " (" << thisNode.getKey().toString(16) << ")]\n"
<< " Ping RPC timeout: id=" << rpcId << endl;
// call join dependant on return value?
}
void oversim::Chord::proxCallback ( const TransportAddress node,
int  rpcId,
cPolymorphic *  contextPointer,
Prox  prox 
)
virtual

Implements ProxListener.

Definition at line 1325 of file Chord.cc.

{
if (prox == Prox::PROX_TIMEOUT) {
// call join dependant on return value?
return;
}
}
void oversim::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.

Parameters
msgThe overlay message to be sent to the UDP layer

Reimplemented from BaseOverlay.

Reimplemented in oversim::Koorde.

Definition at line 678 of file Chord.cc.

{
BaseOverlayMessage* innerMsg = msg;
while (innerMsg->getType() != APPDATA &&
innerMsg->getEncapsulatedPacket() != NULL) {
innerMsg =
static_cast<BaseOverlayMessage*>(innerMsg->getEncapsulatedPacket());
}
switch (innerMsg->getType()) {
ChordMessage* chordMsg = dynamic_cast<ChordMessage*>(innerMsg);
switch(chordMsg->getCommand()) {
newsuccessorhintBytesSent += msg->getByteLength());
break;
}
break;
}
case RPC: {
if ((dynamic_cast<StabilizeCall*>(innerMsg) != NULL) ||
(dynamic_cast<StabilizeResponse*>(innerMsg) != NULL)) {
msg->getByteLength());
} else if ((dynamic_cast<NotifyCall*>(innerMsg) != NULL) ||
(dynamic_cast<NotifyResponse*>(innerMsg) != NULL)) {
msg->getByteLength());
} else if ((dynamic_cast<FixfingersCall*>(innerMsg) != NULL) ||
(dynamic_cast<FixfingersResponse*>(innerMsg) != NULL)) {
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.

Parameters
callRPC Parameter Message

Definition at line 1230 of file Chord.cc.

{
FixfingersResponse* fixfingersResponse =
new FixfingersResponse("FixfingersResponse");
fixfingersResponse->setSucNodeArraySize(1);
fixfingersResponse->setSucNode(0, thisNode);
fixfingersResponse->setSucNodeArraySize(((successorList->getSize() + 1
for (unsigned int i = 0;
fixfingersResponse->setSucNode(i + 1,
}
}
fixfingersResponse->setFinger(call->getFinger());
fixfingersResponse->setBitLength(FIXFINGERSRESPONSE_L(fixfingersResponse));
sendRpcResponse(call, fixfingersResponse);
}
void oversim::Chord::rpcJoin ( JoinCall call)
protectedvirtual

Join Remote-Procedure-Call.

Parameters
callRPC Parameter Message

Reimplemented in oversim::Koorde.

Definition at line 919 of file Chord.cc.

{
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
// we are the only node in the ring
joinResponse->setPreNode(thisNode);
} else {
joinResponse->setPreNode(predecessorNode);
}
joinResponse->setBitLength(JOINRESPONSE_L(joinResponse));
sendRpcResponse(joinCall, joinResponse);
// 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
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);
}
}
}
// if we don't have a successor, the requestor is also our new successor
}
void oversim::Chord::rpcNotify ( NotifyCall call)
protectedvirtual

NOTIFY Remote-Procedure-Call.

Parameters
callRPC Parameter Message

Definition at line 1108 of file Chord.cc.

{
// our predecessor seems to be alive
}
bool newPredecessorSet = false;
NodeHandle newPredecessor = call->getSrcNode();
// is the new predecessor closer than the current one?
(!call->getFailed().isUnspecified() &&
call->getFailed() == predecessorNode)) {
(newPredecessor != predecessorNode)) {
// set up new predecessor
NodeHandle oldPredecessor = predecessorNode;
predecessorNode = newPredecessor;
successorList->addSuccessor(newPredecessor);
}
newPredecessorSet = true;
// send update to application if we've got a new predecessor
if (!oldPredecessor.isUnspecified()) {
callUpdate(oldPredecessor, false);
}
// inform the original predecessor about the new predecessor
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 (!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.

Parameters
callRPC Parameter Message

Definition at line 1057 of file Chord.cc.

{
// our predecessor seems to be alive
}
// 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 1382 of file Chord.cc.

{
if (ev.isGUI()) {
std::stringstream ttString;
// show our predecessor and successor in tooltip
ttString << predecessorNode << endl << thisNode << endl
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
"m=m,50,0,50,0;ls=red,1");
"m=m,50,100,50,100;ls=green,1");
}
}

Friends And Related Function Documentation

friend class ChordFingerTable
friend

Definition at line 271 of file Chord.h.

friend class ChordSuccessorList
friend

Definition at line 270 of file Chord.h.

Member Data Documentation

bool oversim::Chord::aggressiveJoinMode
protected

use modified (faster) JOIN protocol

Definition at line 89 of file Chord.h.

TransportAddress oversim::Chord::bootstrapNode
protected

node used to bootstrap

Definition at line 131 of file Chord.h.

cMessage* oversim::Chord::checkPredecessor_timer
protected

Definition at line 105 of file Chord.h.

double oversim::Chord::checkPredecessorDelay
protected

Definition at line 87 of file Chord.h.

bool oversim::Chord::extendedFingerTable
protected

Definition at line 90 of file Chord.h.

TransportAddress oversim::Chord::failedSuccessor
private

Definition at line 274 of file Chord.h.

ChordFingerTable* oversim::Chord::fingerTable
protected

pointer to this node's finger table

Definition at line 134 of file Chord.h.

cMessage* oversim::Chord::fixfingers_timer
protected

Definition at line 104 of file Chord.h.

int oversim::Chord::fixfingersBytesSent
protected

Definition at line 116 of file Chord.h.

int oversim::Chord::fixfingersCount
protected

Definition at line 110 of file Chord.h.

double oversim::Chord::fixfingersDelay
protected

Definition at line 86 of file Chord.h.

cMessage* oversim::Chord::join_timer
protected

Definition at line 102 of file Chord.h.

int oversim::Chord::joinBytesSent
protected

Definition at line 113 of file Chord.h.

int oversim::Chord::joinCount
protected

Definition at line 108 of file Chord.h.

double oversim::Chord::joinDelay
protected

Definition at line 84 of file Chord.h.

int oversim::Chord::joinRetry
protected

Definition at line 82 of file Chord.h.

int oversim::Chord::keyLength
protected

length of an overlay key in bits

Definition at line 119 of file Chord.h.

bool oversim::Chord::memorizeFailedSuccessor
protected

Definition at line 93 of file Chord.h.

bool oversim::Chord::mergeOptimizationL1
protected

Definition at line 95 of file Chord.h.

bool oversim::Chord::mergeOptimizationL2
protected

Definition at line 96 of file Chord.h.

bool oversim::Chord::mergeOptimizationL3
protected

Definition at line 97 of file Chord.h.

bool oversim::Chord::mergeOptimizationL4
protected

Definition at line 98 of file Chord.h.

int oversim::Chord::missingPredecessorStabRequests
protected

missing StabilizeCall msgs

Definition at line 120 of file Chord.h.

bool oversim::Chord::newChordFingerTable
protected

Definition at line 94 of file Chord.h.

int oversim::Chord::newsuccessorhintBytesSent
protected

Definition at line 117 of file Chord.h.

int oversim::Chord::newsuccessorhintCount
protected

Definition at line 112 of file Chord.h.

int oversim::Chord::notifyBytesSent
protected

Definition at line 115 of file Chord.h.

int oversim::Chord::notifyCount
protected

Definition at line 111 of file Chord.h.

unsigned int oversim::Chord::numFingerCandidates
protected

Definition at line 91 of file Chord.h.

NodeHandle oversim::Chord::predecessorNode
protected

predecessor of this node

Definition at line 130 of file Chord.h.

bool oversim::Chord::proximityRouting
protected

Definition at line 92 of file Chord.h.

cMessage* oversim::Chord::stabilize_timer
protected

Definition at line 103 of file Chord.h.

int oversim::Chord::stabilizeBytesSent
protected

Definition at line 114 of file Chord.h.

int oversim::Chord::stabilizeCount
protected

Definition at line 109 of file Chord.h.

double oversim::Chord::stabilizeDelay
protected

stabilize interval (secs)

Definition at line 85 of file Chord.h.

int oversim::Chord::stabilizeRetry
protected

// retries before neighbor considered failed

Definition at line 83 of file Chord.h.

ChordSuccessorList* oversim::Chord::successorList
protected

pointer to this node's successor list

Definition at line 135 of file Chord.h.

int oversim::Chord::successorListSize
protected

Definition at line 88 of file Chord.h.


The documentation for this class was generated from the following files: