BaseOverlay Class Reference

#include <BaseOverlay.h>

Inheritance diagram for BaseOverlay:

BaseRpc RpcListener Broose Chord Gia Pastry Vast Koorde List of all members.

Detailed Description

Base class for overlays.

Base class for overlay modules, with KBR-API, statistics and pointers to the BootstrapOracle and the UnderlayConfigurator. A minimal overlay has to implement numInitStages(), route(), handleUDPMessage() and receiveChangeNotification(). Derived classes must use BaseOverlayMessage as base class for own message types.

Author:
Bernhard Heep (initial)

Sebastian Mies (rpc, lookup)


Public Member Functions

virtual ~BaseOverlay ()
 Virtual destructor.
bool isMalicious ()
 Returns true, if node is malicious.
NodeHandlegetThisNode ()
 Returns the NodeHandle of this node.
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)
 
Parameters:
num 

virtual bool isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err)
 Query if a node is among the siblings for a given key.
virtual int getMaxNumSiblings ()
 Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.
virtual int getMaxNumRedundantNodes ()
 Query the maximum number of redundant next hop nodes that are returned by findNode().
void sendMessageToUDP (const TransportAddress &dest, BaseOverlayMessage *msg)
 Sends message to underlay.
void pingNode (const TransportAddress &dest, simtime_t timeout=-1, int retries=0, const char *caption=NULL, RpcListener *rpcListener=NULL, int rpcId=-1)
 ping a node by its TransportAddress
void pingKey (const OverlayKey &destKey, simtime_t timeout=-1, int retries=0, const char *caption=NULL, RpcListener *rpcListener=NULL, int rpcId=-1)
 ping a node by its OverlayKey
void sendToKey (const OverlayKey &key, BaseOverlayMessage *message, int numSiblings=1, const TransportAddress &nextHop=TransportAddress::UNSPECIFIED_NODE)
 Sends a message to an overlay node, with the generic routing algorithm.

Protected Types

typedef hash_set< AbstractLookup *,
lookupHashFcn, lookupHashFcn
LookupSet

Protected Member Functions

int numInitStages () const
 Sets init stage.
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void finishOverlay ()
 collects statistical data in derived class
virtual void bindToPort (int port)
 Tells UDP we want to get all packets arriving on the given port.
virtual void sendToUDP (cMessage *msg, int srcPort, const IPvXAddress &destAddr, int destPort)
 Sends a packet over UDP.
virtual void printPacket (cMessage *msg)
 Prints a brief about packets having an attached UDPControlInfo (i.e.
virtual void route (const OverlayKey &key, cMessage *msg, const NodeHandle &hint=NodeHandle::UNSPECIFIED_NODE)
 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.
virtual void handleUDPMessage (BaseOverlayMessage *msg)=0
 Processes messages from underlay.
virtual void handleTimerEvent (cMessage *msg)
 Processes "timer" self-messages.
virtual void handleAppMessage (cMessage *msg)
 Processes non-commonAPI messages.
virtual void recordOverlaySentStats (BaseOverlayMessage *msg)
 Collect overlay specific sent messages statistics.
void setReadyIcon (bool ready)
 Colors module-icon blue (ready) or red (not ready).
void showOverlayNeighborArrow (const NodeHandle &neighbor, bool flush=true, char *displayString=NULL)
 Draws an arrow from this node to neighbor.
void deleteOverlayNeighborArrow (const NodeHandle &neighbor)
 Removes an arrow from this node to neighbor.
virtual AbstractLookupcreateLookup (const BaseOverlayMessage *msg=NULL)
 Creates an abstract iterative lookup instance.
virtual void removeLookup (AbstractLookup *lookup)
 Removes the abstract lookup instance.
virtual OverlayKey distance (const OverlayKey &x, const OverlayKey &y) const
 This method should implement the distance between two keys.
virtual NodeVectorfindNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg=NULL)
 Implements the find node call.
virtual void joinOverlay ()
 Join the overlay with a given nodeID in thisNode.key.
virtual bool handleFailedNode (const TransportAddress &failed)
 Handles a failed node.
virtual PingResponse * ping (PingCall *call)
 Implements a ping call.
virtual void lookupRpc (LookupCall *call)
void countFindNodeCall (const FindNodeCall *call)
void countFailedNodeCall (const FailedNodeCall *call)
void sendRpcMessageToDestination (int destType, const TransportAddress &dest, const OverlayKey &destKey, BaseOverlayMessage *message)
bool internalHandleRpc (BaseCallMessage *msg)
 Handles internal rpc requests.

Protected Attributes

int numForwarded
int bytesForwarded
int numSignalingForwarded
int bytesSignalingForwarded
int numPingSent
int bytesPingSent
int numPingResponseSent
int bytesPingResponseSent
int numFindNodeSent
int bytesFindNodeSent
int numFindNodeResponseSent
int bytesFindNodeResponseSent
int numFailedNodeSent
int bytesFailedNodeSent
int numFailedNodeResponseSent
int bytesFailedNodeResponseSent
simtime_t creationTime
cModule * thisTerminal
BootstrapOraclebootstrapOracle
GlobalStatisticsglobalStatistics
NotificationBoard * notificationBoard
UnderlayConfiguratorunderlayConfigurator
bool debugOutput
bool measureNetwInitPhase
bool onlyCommonAPIMessages
bool useBaseLookup
bool iterativeLookup
bool useCommonAPIforward
int localPort
int hopCountMax
int numDropped
int bytesDropped
cOutVector delayVector
cOutVector hopCountVector
BaseLookupConfiguration baseLookupConfig
LookupSet lookups

Private Types

enum  Direction { IN, OUT }

Private Member Functions

void initialize (int stage)
 initializes base-class-attributes
void finish ()
 collects statistical data
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
.
void compactGateArray (cModule *terminal, enum Direction dir)
 compacts arrow gate-array
void initLookups ()
 creates a LookupSet
void finishLookups ()
 deletes entries in lookups
void internalRoute (const OverlayKey &key, cMessage *msg, const NodeHandle &hint=NodeHandle::UNSPECIFIED_NODE)
 calls route(const OverlayKey& key, cMessage* msg, const NodeHandle& hint) if useBaseLookup is false, else sendToKey(const OverlayKey& key, BaseOverlayMessage* msg, uint numNeighbors, const TransportAddress& nextHop)
virtual void forwardMessageRecursive (const TransportAddress &dest, BaseRouteMessage *msg)
 Hook for forwarded message in recursive lookup mode.
void findNodeRpc (FindNodeCall *call)
void failedNodeRpc (FailedNodeCall *call)
void pingRpc (PingCall *call)
PingCall * createPingCall (const char *caption)

Private Attributes

int numSent
int bytesSent
int numSignalingSent
int bytesSignalingSent
int numReceived
int bytesReceived
int numSignalingReceived
int bytesSignalingReceived
cGate * thisOutGateArray
cGate * thisInGateArray
bool drawOverlayTopology

Friends

class BaseLookup
class BasePathLookup

Classes

class  lookupHashFcn


Member Typedef Documentation

typedef hash_set<AbstractLookup*, lookupHashFcn, lookupHashFcn> BaseOverlay::LookupSet [protected]


Member Enumeration Documentation

enum BaseOverlay::Direction [private]

Enumerator:
IN 
OUT 
00451 { IN, OUT };


Constructor & Destructor Documentation

BaseOverlay::~BaseOverlay (  )  [virtual]

Virtual destructor.

00049 {
00050     finishLookups();
00051     finishRpcs();
00052 }


Member Function Documentation

void BaseOverlay::initialize ( int  stage  )  [private]

initializes base-class-attributes

Parameters:
stage the init stage
00060 {
00061     if(stage == MIN_STAGE_OVERLAY) {
00062         OverlayKey::setKeyLength(par("keyLength"));
00063 
00064         // fetch some parameters
00065         debugOutput                     = par("debugOutput");
00066         measureNetwInitPhase            = par("measureNetwInitPhase");
00067         localPort                       = par("localPort");
00068         hopCountMax                     = par("hopCountMax");
00069         drawOverlayTopology             = par("drawOverlayTopology");
00070         useBaseLookup                   = par("useBaseLookup");
00071         iterativeLookup                 = par("iterativeLookup");
00072         useCommonAPIforward             = false;
00073         onlyCommonAPIMessages           = true;
00074 
00075         // set base lookup parameters
00076         baseLookupConfig.redundantNodes = par("lookupRedundantNodes");
00077         baseLookupConfig.parallelPaths  = par("lookupParallelPaths");
00078         baseLookupConfig.parallelRpcs   = par("lookupParallelRpcs");
00079         baseLookupConfig.secure         = par("lookupSecure");
00080         baseLookupConfig.merge          = par("lookupMerge");
00081         baseLookupConfig.failedNodeRpcs = par("lookupFailedNodeRpcs");
00082 
00083         // statistics
00084         numSent = 0;
00085         bytesSent = 0;
00086         numSignalingSent = 0;
00087         bytesSignalingSent = 0;
00088         numReceived = 0;
00089         bytesReceived = 0;
00090         numSignalingReceived = 0;
00091         bytesSignalingReceived = 0;
00092         numForwarded = 0;
00093         bytesForwarded = 0;
00094         numSignalingForwarded = 0;
00095         bytesSignalingForwarded = 0;
00096         numDropped = 0;
00097         bytesDropped = 0;
00098         numPingSent = 0;
00099         bytesPingSent = 0;
00100         numPingResponseSent = 0;
00101         bytesPingResponseSent = 0;
00102         numFindNodeSent = 0;
00103         bytesFindNodeSent = 0;
00104         numFindNodeResponseSent = 0;
00105         bytesFindNodeResponseSent = 0;
00106         numFailedNodeSent = 0;
00107         bytesFailedNodeSent = 0;
00108         numFailedNodeResponseSent = 0;
00109         bytesFailedNodeResponseSent = 0;
00110 
00111         WATCH(numSent);
00112         WATCH(bytesSent);
00113         WATCH(numSignalingSent);
00114         WATCH(bytesSignalingSent);
00115         WATCH(numReceived);
00116         WATCH(bytesReceived);
00117         WATCH(numSignalingReceived);
00118         WATCH(bytesSignalingReceived);
00119         WATCH(numForwarded);
00120         WATCH(bytesForwarded);
00121         WATCH(numSignalingForwarded);
00122         WATCH(bytesSignalingForwarded);
00123         WATCH(numDropped);
00124         WATCH(bytesDropped);
00125         WATCH(numPingSent);
00126         WATCH(bytesPingSent);
00127         WATCH(numPingResponseSent);
00128         WATCH(bytesPingResponseSent);
00129         WATCH(numFindNodeSent);
00130         WATCH(bytesFindNodeSent);
00131         WATCH(numFindNodeResponseSent);
00132         WATCH(bytesFindNodeResponseSent);
00133         WATCH(numFailedNodeSent);
00134         WATCH(bytesFailedNodeSent);
00135         WATCH(numFailedNodeResponseSent);
00136         WATCH(bytesFailedNodeResponseSent);
00137 
00138         // set up UDP
00139         bindToPort(localPort);
00140 
00141         // find friend modules
00142         bootstrapOracle = BootstrapOracleAccess().get();
00143         underlayConfigurator = UnderlayConfiguratorAccess().get();
00144         globalStatistics = GlobalStatisticsAccess().get();
00145         notificationBoard = NotificationBoardAccess().get();
00146 
00147         thisTerminal = parentModule()->parentModule();
00148 
00149         // set up local nodehandle
00150         //thisNode.moduleId = parentModule()->id();
00151         thisNode.ip = IPAddressResolver().
00152                       addressOf(parentModule()->parentModule()).get4();
00153         thisNode.port = localPort;
00154         thisNode.key = OverlayKey::UNSPECIFIED_KEY;
00155 
00156         // set up arrow-gates
00157         thisOutGateArray = thisTerminal->gate("overlayNeighborArrowOut");
00158         thisInGateArray = thisTerminal->gate("overlayNeighborArrowIn");
00159         thisTerminal->setGateSize("overlayNeighborArrowOut" ,1);
00160         thisTerminal->setGateSize("overlayNeighborArrowIn" ,1);
00161 
00162         // subscribe to the notification board
00163         notificationBoard->subscribe( this, NF_HOSTPOSITION_UPDATED);
00164         notificationBoard->subscribe( this, NF_OVERLAY_NODE_LEAVE);
00165 
00166         // init rpcs
00167         initRpcs();
00168         initLookups();
00169 
00170         // statistics
00171         globalStatistics->nodesInitialized++;
00172         creationTime = simTime();
00173     }
00174 
00175 
00176     if (stage >= MIN_STAGE_OVERLAY && stage <= MAX_STAGE_OVERLAY)
00177         initializeOverlay(stage);
00178 
00179     if (stage == MAX_STAGE_OVERLAY) {
00180 //      setReadyIcon(false);
00181         if ((bool)par("joinOnApplicationRequest") == false) {
00182             join();
00183         }
00184     }
00185 }

void BaseOverlay::finish (  )  [private]

collects statistical data

00193 {
00194     finishOverlay();
00195     finishLookups();
00196     finishRpcs();
00197 
00198     globalStatistics->nodesFinished++;
00199 
00200     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00201     if(time == 0) return;
00202 
00203     globalStatistics->addStdDev("BaseOverlay: Sent User Messages/s", numSent / time);
00204     globalStatistics->addStdDev("BaseOverlay: Sent User Bytes/s", bytesSent / time);
00205     globalStatistics->addStdDev("BaseOverlay: Sent Signaling Messages/s", numSignalingSent / time);
00206     globalStatistics->addStdDev("BaseOverlay: Sent Signaling Bytes/s", bytesSignalingSent / time);
00207     globalStatistics->addStdDev("BaseOverlay: Sent Total Messages", numSent + numSignalingSent);
00208     globalStatistics->addStdDev("BaseOverlay: Sent Total Bytes", bytesSent + bytesSignalingSent);
00209     globalStatistics->addStdDev("BaseOverlay: Sent FindNode Messages/s", numFindNodeSent / time);
00210     globalStatistics->addStdDev("BaseOverlay: Sent FindNode Bytes/s", bytesFindNodeSent / time);
00211 
00212     globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Messages/s", numFindNodeResponseSent / time);
00213     globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Bytes/s", bytesFindNodeResponseSent / time);
00214     globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Messages/s", numFailedNodeSent / time);
00215     globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Bytes/s", bytesFailedNodeSent / time);
00216     globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Messages/s", numFailedNodeResponseSent / time);
00217     globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Bytes/s", bytesFailedNodeResponseSent / time);
00218 
00219     globalStatistics->addStdDev("BaseOverlay: Received User Messages/s", numReceived / time);
00220     globalStatistics->addStdDev("BaseOverlay: Received User Bytes/s", bytesReceived / time);
00221     globalStatistics->addStdDev("BaseOverlay: Received Signaling Messages/s", numSignalingReceived / time);
00222     globalStatistics->addStdDev("BaseOverlay: Received Signaling Bytes/s", bytesSignalingReceived / time);
00223     globalStatistics->addStdDev("BaseOverlay: Received Total Messages", numReceived
00224                  + numSignalingReceived);
00225     globalStatistics->addStdDev("BaseOverlay: Received Total Bytes", bytesReceived
00226                  + bytesSignalingReceived);
00227     globalStatistics->addStdDev("BaseOverlay: Forwarded User Messages/s", numForwarded / time);
00228     globalStatistics->addStdDev("BaseOverlay: Forwarded User Bytes/s", bytesForwarded / time);
00229     globalStatistics->addStdDev("BaseOverlay: Forwarded Signaling Messages/s", numSignalingForwarded / time);
00230     globalStatistics->addStdDev("BaseOverlay: Forwarded Signaling Bytes/s", bytesSignalingForwarded / time);
00231     globalStatistics->addStdDev("BaseOverlay: Forwarded Total Messages", numForwarded
00232                  + numSignalingForwarded);
00233     globalStatistics->addStdDev("BaseOverlay: Forwarded Total Bytes", bytesForwarded
00234                  + bytesSignalingForwarded);
00235 
00236     globalStatistics->addStdDev("BaseOverlay: Dropped Messages/s", numDropped / time);
00237     globalStatistics->addStdDev("BaseOverlay: Dropped Bytes/s", bytesDropped / time);
00238 
00239     globalStatistics->addStdDev("BaseOverlay: Active Time", simTime() - creationTime);
00240 
00241     globalStatistics->doFinish();
00242 
00243 }

int BaseOverlay::numInitStages (  )  const [protected]

Sets init stage.

See also:
InitStages.h
00055 {
00056     return MAX_STAGE_OVERLAY + 1;
00057 }

void BaseOverlay::initializeOverlay ( int  stage  )  [protected, 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:
stage the init stage

Reimplemented in Broose, Chord, Gia, Koorde, Pastry, and Vast.

00188 {
00189     // ...
00190 }

void BaseOverlay::finishOverlay (  )  [protected, virtual]

collects statistical data in derived class

Reimplemented in Broose, Chord, Gia, Koorde, Pastry, and Vast.

00246 {
00247     // ...
00248 }

bool BaseOverlay::isMalicious (  ) 

Returns true, if node is malicious.

Returns:
true, if node is malicious.
00254 {
00255     return bootstrapOracle->isMalicious(getThisNode());
00256 }

NodeHandle & BaseOverlay::getThisNode (  ) 

Returns the NodeHandle of this node.

Returns:
the NodeHandle of this node.
00259 {
00260     return thisNode;
00261 }

void BaseOverlay::bindToPort ( int  port  )  [protected, virtual]

Tells UDP we want to get all packets arriving on the given port.

00267 {
00268     EV << "Binding to UDP port " << port << endl;
00269 
00270     // TODO UDPAppBase should be ported to use UDPSocket sometime, but for now
00271     // we just manage the UDP socket by hand...
00272     cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00273     UDPControlInfo *ctrl = new UDPControlInfo();
00274     ctrl->setSrcPort(port);
00275     ctrl->setSockId(UDPSocket::generateSocketId());
00276     msg->setControlInfo(ctrl);
00277     send(msg, "to_udp");
00278 }

void BaseOverlay::sendToUDP ( cMessage *  msg,
int  srcPort,
const IPvXAddress &  destAddr,
int  destPort 
) [protected, virtual]

Sends a packet over UDP.

00282 {
00283     // send message to UDP, with the appropriate control info attached
00284     msg->setKind(UDP_C_DATA);
00285 
00286     UDPControlInfo *ctrl = new UDPControlInfo();
00287     ctrl->setSrcPort(srcPort);
00288     ctrl->setDestAddr(destAddr);
00289     ctrl->setDestPort(destPort);
00290     msg->setControlInfo(ctrl);
00291 
00292     EV << "Sending packet: ";
00293     printPacket(msg);
00294 
00295     send(msg, "to_udp");
00296 }

void BaseOverlay::printPacket ( cMessage *  msg  )  [protected, virtual]

Prints a brief about packets having an attached UDPControlInfo (i.e.

those which just arrived from UDP, or about to be send to UDP).

00299 {
00300     UDPControlInfo *ctrl = check_and_cast<UDPControlInfo *>(msg->controlInfo());
00301 
00302     IPvXAddress srcAddr = ctrl->srcAddr();
00303     IPvXAddress destAddr = ctrl->destAddr();
00304     int srcPort = ctrl->srcPort();
00305     int destPort = ctrl->destPort();
00306 
00307     ev  << msg << "  (" << msg->byteLength() << " bytes)" << endl;
00308     ev  << srcAddr << " :" << srcPort << " --> " << destAddr << ":" << destPort 
00309 << endl;
00310 }

void BaseOverlay::route ( const OverlayKey key,
cMessage *  msg,
const NodeHandle hint = NodeHandle::UNSPECIFIED_NODE 
) [protected, virtual]

Routes message through overlay.

The default implementation uses FindNode to determine next hops and a generic greedy routing algorithm provides with SendToKey.

Parameters:
key destination key
msg message to route
hint next hop (usually unused)

Reimplemented in Gia.

00321 {}

void BaseOverlay::callDeliver ( BaseOverlayMessage *  msg,
const OverlayKey destKey 
) [protected]

Calls deliver function in application.

Encapsulates messages in KBRdeliver messages and sends them to application.

Parameters:
msg delivered message
00326 {
00327     KBRdeliver* deliverMsg = new KBRdeliver();
00328 
00329     OverlayCtrlInfo* overlayCtrlInfo =
00330         check_and_cast<OverlayCtrlInfo*>
00331         (msg->removeControlInfo());
00332 
00333     deliverMsg->setControlInfo(overlayCtrlInfo);
00334     deliverMsg->setDestKey(destKey);
00335 
00336     deliverMsg->encapsulate(msg->decapsulate());
00337 
00338     deliverMsg->setType(KBR_DELIVER);
00339 
00340     send(deliverMsg, "to_app");
00341 
00342     delete msg;
00343 }

void BaseOverlay::callForward ( const OverlayKey key,
BaseRouteMessage *  msg,
const NodeHandle nextHopNode 
) [protected]

Calls forward function in application.

Encapsulates messages in KBRforward messages and sends them to application.
the message to be sent through the API must be encapsulated in msg.

Parameters:
key destination key
msg message to forward
nextHopNode next hop
00347 {
00348     KBRforward* forwardMsg = new KBRforward();
00349 
00350     forwardMsg->setDestKey(msg->getDestKey());
00351     forwardMsg->setNextHopNode(nextHopNode);
00352     forwardMsg->encapsulate(msg->encapsulatedMsg()->decapsulate());
00353 
00354     OverlayCtrlInfo* overlayCtrlInfo =
00355         new OverlayCtrlInfo();
00356     //overlayCtrlInfo->setThisNode(thisNode);
00357     overlayCtrlInfo->setHopCount(msg->getHopCount());
00358     overlayCtrlInfo->setSrcNode(msg->getSrcNode());
00359 
00360     if(msg->controlInfo() != NULL) {
00361         OverlayCtrlInfo* ctrlInfo =
00362             check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
00363         overlayCtrlInfo->setLastHopAddr(ctrlInfo->getLastHopAddr());
00364         overlayCtrlInfo->setLastHopPort(ctrlInfo->getLastHopPort());
00365 
00366         delete ctrlInfo;
00367     }
00368 
00369     forwardMsg->setControlInfo(overlayCtrlInfo);
00370 
00371     forwardMsg->setType(KBR_FORWARD);
00372 
00373     send(forwardMsg, "to_app");
00374 
00375     delete msg;
00376 }

void BaseOverlay::callUpdate ( const NodeHandle node,
bool  joined 
) [protected]

Informs application about state changes of nodes or newly joined nodes.

Creates a KBRUpdate message and sends it up to the application

Parameters:
node the node that has joined or changed its state
joined has the node joined or changed its state?
00421 {
00422     KBRupdate* updateMsg = new KBRupdate("UPDATE");
00423 
00424     updateMsg->setNode(node);
00425     updateMsg->setJoined(joined);
00426 
00427     updateMsg->setType(KBR_UPDATE);
00428 
00429     send(updateMsg, "to_app");//"to_upperTier");
00430 }

void BaseOverlay::join ( const OverlayKey nodeID = OverlayKey::UNSPECIFIED_KEY  ) 

Join the overlay with a given nodeID.

Join the overlay with a given nodeID. 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.

Parameters:
nodeID The new nodeID for this node.
00396 {
00397     Enter_Method("join()");
00398 
00399     // set nodeID and IP
00400     thisNode.ip = 
00401         IPAddressResolver().addressOf(parentModule()->parentModule()).get4();
00402     if (nodeID.isUnspecified())  {
00403         thisNode.key = OverlayKey::random();
00404     }
00405 
00406     callUpdate(thisNode, true);
00407 
00408     joinOverlay();
00409 }

NodeVector * BaseOverlay::local_lookup ( const OverlayKey key,
int  num,
bool  safe 
) [virtual]

finds nodes closest to the given OverlayKey

calls findNode() (that should be overridden in derived overlay) and returns a list with (num) nodes ordered by distance to the node defined by key.

Parameters:
key the given node
num number of nodes that are returned
safe 
00380 {
00381     Enter_Method("local_lookup()");
00382 
00383     if (safe == true) {
00384         error("BaseOverlay::local_lookup(): safe flag is not implemented!");
00385     }
00386 
00387     NodeVector* nodeVector = findNode(key, num, num);
00388 
00389     if(((int)nodeVector->size()) > num)
00390         nodeVector->resize(num);
00391 
00392     return nodeVector;
00393 }

NodeVector * BaseOverlay::neighborSet ( int  num  )  [virtual]

Parameters:
num 

00413 {
00414     Enter_Method("neighborSet()");
00415 
00416     return local_lookup(thisNode.key, num, false);
00417 }

bool BaseOverlay::isSiblingFor ( const NodeHandle node,
const OverlayKey key,
int  numSiblings,
bool *  err 
) [virtual]

Query if a node is among the siblings for a given key.

Query if a node is among the siblings for a given key. This means, that the nodeId of this node is among the closest numSiblings nodes to the key and that by a local findNode() call all other siblings to this key can be retrieved.

Parameters:
node the NodeHandle
key destination key
numSiblings The nodes knows all numSiblings nodes close to this key
err return false if the range could not be determined
Returns:
bool true, if the node is responsible for the key.

Reimplemented in Broose, Chord, and Pastry.

00434 {
00435     Enter_Method("isSiblingFor()");
00436 
00437     opp_error( "isSiblingFor: Not implemented!" );
00438 
00439     return false;
00440 }

int BaseOverlay::getMaxNumSiblings (  )  [virtual]

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

Returns:
int number of siblings.

Reimplemented in Broose, Chord, and Pastry.

00443 {
00444     Enter_Method("getMaxNumSiblings()");
00445 
00446     opp_error( "getMaxNumSiblings: Not implemented!" );
00447 
00448     return false;
00449 }

int BaseOverlay::getMaxNumRedundantNodes (  )  [virtual]

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

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

Reimplemented in Broose, Chord, and Pastry.

00452 {
00453     Enter_Method("getMaxNumRedundantNodes()");
00454 
00455     opp_error( "getMaxNumRedundantNodes: Not implemented!" );
00456 
00457     return false;
00458 }

void BaseOverlay::handleMessage ( cMessage *  msg  )  [private]

Checks for message type and calls corresponding method.


Checks for message type (from UDP/App or selfmessage) and calls corresponding method like route(), get(), put(), remove(), handleTimerEvent(), handleAppMessage() and handleUDPMessage().

Parameters:
msg The message to be handled
00467 {
00468     // process self-messages
00469     if (msg->isSelfMessage()) {
00470         // process rpc self-messages
00471         BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg);
00472         if (rpcMessage!=NULL) {
00473             internalHandleRpcMessage(rpcMessage);
00474             return;
00475         }
00476         // process all other self-messages
00477         handleTimerEvent(msg);
00478     }
00479 
00480     // process messages from UDP
00481     else if (msg->arrivedOn("from_udp")) {
00482         UDPControlInfo* udpControlInfo =
00483             check_and_cast<UDPControlInfo*>(msg->removeControlInfo());
00484         OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo;
00485         overlayCtrlInfo->setLastHopAddr(udpControlInfo->srcAddr());
00486         overlayCtrlInfo->setLastHopPort(udpControlInfo->srcPort());
00487         msg->setControlInfo(overlayCtrlInfo);
00488         delete udpControlInfo;
00489 
00490         BaseOverlayMessage* baseOverlayMsg =
00491             dynamic_cast<BaseOverlayMessage*>(msg);
00492 
00493         if (baseOverlayMsg == NULL) {
00494             delete msg;
00495             return;
00496         }
00497 
00498         // records stats if message is not a UDP "self message"
00499         if (overlayCtrlInfo->getLastHopAddr() != thisNode.ip) {
00500             if (baseOverlayMsg->getSignaling() == false)
00501                 RECORD_STATS(numReceived++; bytesReceived +=
00502                                  baseOverlayMsg->byteLength());
00503             else
00504                 RECORD_STATS(numSignalingReceived++;bytesSignalingReceived
00505                              += baseOverlayMsg->byteLength());
00506         }
00507 
00508         handleBaseOverlayMessage(baseOverlayMsg);
00509     }
00510 
00511     // process CommonAPIMessages from App
00512     else if (dynamic_cast<CommonAPIMessage*>(msg) != NULL) {
00513         if (dynamic_cast<KBRroute*>(msg) != NULL) {
00514             KBRroute* apiMsg = dynamic_cast<KBRroute*>(msg);
00515 
00516             internalRoute(apiMsg->getDestKey(), apiMsg->decapsulate(),
00517                           apiMsg->getHint());
00518         }
00519 
00520         else if (dynamic_cast<KBRforward*>(msg) != NULL) {
00521             KBRforward* apiMsg = dynamic_cast<KBRforward*>(msg);
00522             OverlayCtrlInfo* overlayCtrlInfo =
00523                 check_and_cast<OverlayCtrlInfo*>
00524                 (msg->removeControlInfo());
00525 
00526             BaseAppDataMessage* dataMsg =
00527                 new BaseAppDataMessage();
00528             dataMsg->setType(APPDATA);
00529             dataMsg->setLength(BASEAPPDATA_L(dataMsg));
00530             dataMsg->setName(msg->encapsulatedMsg()->name());
00531             dataMsg->encapsulate(msg->decapsulate());
00532             dataMsg->setSignaling(false);
00533 
00534             BaseRouteMessage* routeMsg = new BaseRouteMessage(dataMsg->name());
00535             routeMsg->setType(OVERLAYROUTE);
00536             routeMsg->setLength(BASEROUTE_L(routeMsg));
00537             routeMsg->encapsulate(dataMsg);
00538 
00539             routeMsg->setSignaling(false);
00540             routeMsg->setDestKey(apiMsg->getDestKey());
00541             routeMsg->setSrcNode(overlayCtrlInfo->getSrcNode());
00542             routeMsg->setHopCount(overlayCtrlInfo->getHopCount());
00543             routeMsg->setControlInfo(overlayCtrlInfo);
00544 
00545             routeMsg->setKind(ALREADY_FORWARDED);
00546 
00547             sendToKey(apiMsg->getDestKey(), routeMsg, 1, apiMsg->getNextHopNode());
00548         }
00549 
00550         delete msg;
00551     } 
00552 
00553     else if (dynamic_cast<BaseRpcMessage*>(msg) != NULL) {
00554             BaseRpcMessage* rpcMessage =
00555                 dynamic_cast<BaseRpcMessage*>(msg);
00556             internalHandleRpcMessage(rpcMessage);
00557     }
00558 
00559     // process other messages from App
00560     else if (msg->arrivedOn("from_app") && onlyCommonAPIMessages == false)
00561         handleAppMessage(msg);
00562 
00563     else {
00564         opp_error("BaseOverlay::handleMessage(): Received msg with "
00565                   "unknown type!");
00566 //        RECORD_STATS(numDropped++; bytesDropped += msg->byteLength());
00567         delete msg;
00568     }
00569 }

void BaseOverlay::handleBaseOverlayMessage ( BaseOverlayMessage *  msg,
const OverlayKey destKey = OverlayKey::UNSPECIFIED_KEY 
) [private]

Handles a BaseOverlayMessage
.

Handles BaseOverlayMessages of type OVERLAYSIGNALING, RPC, APPDATA or OVERLAYROUTE.

Parameters:
msg The message to be handled
00573 {
00574     switch(msg->getType()) {
00575     case OVERLAYSIGNALING:
00576         handleUDPMessage(msg);
00577         return;
00578 
00579     case RPC: {
00580             // process rpc-messages
00581             BaseRpcMessage* rpcMessage =
00582                 check_and_cast<BaseRpcMessage*>(msg);
00583             internalHandleRpcMessage(rpcMessage);
00584             return;
00585         }
00586 
00587     case APPDATA: {
00588             BaseAppDataMessage* baseAppDataMsg =
00589                 check_and_cast<BaseAppDataMessage*>(msg);
00590             assert(!destKey.isUnspecified());
00591             callDeliver(baseAppDataMsg, destKey);
00592             return;
00593         }
00594 
00595     case OVERLAYROUTE: {
00596             BaseRouteMessage* baseRouteMsg =
00597                 check_and_cast<BaseRouteMessage*>(msg);
00598 
00599             if (baseRouteMsg->getDestKey().isUnspecified())
00600                 opp_error("BaseOverlay: No destination key in ROUTE msg");
00601 
00602 
00603             // if this node is malicious drop the message
00604             if (isMalicious()) {
00605                     EV << "BaseOverlay: BaseRouteMessage gets dropped "
00606                        << "because this node is malicious!" << endl;
00607                     RECORD_STATS(numDropped++;
00608                                  bytesDropped += baseRouteMsg->byteLength());
00609                     delete msg;
00610                     return;
00611             }
00612 
00613             bool err;
00614             if (isSiblingFor(thisNode, baseRouteMsg->getDestKey(),
00615                                 1, &err)) {
00616                 OverlayCtrlInfo* overlayCtrlInfo =
00617                     check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
00618                 
00619                 overlayCtrlInfo->setHopCount(baseRouteMsg->getHopCount());
00620                 overlayCtrlInfo->setSrcNode(baseRouteMsg->getSrcNode());
00621 
00622                 BaseOverlayMessage* tmpMsg
00623                 = check_and_cast<BaseOverlayMessage*>
00624                   (baseRouteMsg->decapsulate());
00625                 tmpMsg->setControlInfo(overlayCtrlInfo);
00626 
00627                 handleBaseOverlayMessage(tmpMsg, baseRouteMsg->getDestKey());//bh
00628                 delete msg;
00629                 return;
00630             } else {
00631                 // forward msg if this node is not responsible for the key
00632                 sendToKey(baseRouteMsg->getDestKey(), baseRouteMsg, 1);
00633                 return;
00634             }
00635             break;
00636         }
00637 
00638     default:
00639         EV << "BaseOverlay::handleMessage(): received unknown message "
00640         << "from UDP of type " << msg->name() << endl;
00641         break;
00642     }
00643 }

virtual void BaseOverlay::handleUDPMessage ( BaseOverlayMessage *  msg  )  [protected, pure virtual]

Processes messages from underlay.

Parameters:
msg Message from UDP

Implemented in Broose, Chord, Gia, Koorde, Pastry, and Vast.

void BaseOverlay::handleTimerEvent ( cMessage *  msg  )  [protected, virtual]

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented in Broose, Chord, Gia, Koorde, Pastry, and Vast.

00648 {
00649     // timer...
00650 }

void BaseOverlay::handleAppMessage ( cMessage *  msg  )  [protected, virtual]

Processes non-commonAPI messages.


Processes non-commonAPI messages if parameter "onlyCommonAPIMessages" is false.

Parameters:
msg non-commonAPIMessage

Reimplemented in Gia, and Vast.

00654 {
00655     delete msg;
00656 }

void BaseOverlay::recordOverlaySentStats ( BaseOverlayMessage *  msg  )  [protected, 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:
msg The overlay message to be sent to the UDP layer

Reimplemented in Broose, Chord, and Koorde.

00660 {
00661     // collect statistics ...
00662 }

void BaseOverlay::compactGateArray ( cModule *  terminal,
enum Direction  dir 
) [private]

compacts arrow gate-array

Parameters:
terminal node
dir in- or out-array?
00812 {
00813     cGate* gateArray = (dir == OUT ? terminal->gate("overlayNeighborArrowOut")
00814                         : terminal->gate("overlayNeighborArrowIn"));
00815     const char* gateName = (dir == OUT ? "overlayNeighborArrowOut"
00816                             : "overlayNeighborArrowIn");
00817 
00818     for (int j = 0; j < gateArray->size() - 1; j++) {
00819         if (terminal->gate(gateName, j)->isConnectedOutside())
00820             continue;
00821 
00822         cGate* tempGate = NULL;
00823         int k = 1;
00824         while ((tempGate == NULL) && ((j + k) != gateArray->size())) {
00825             tempGate = (dir == OUT ? terminal->gate(gateName, j + k)->toGate()
00826                         : terminal->gate(gateName, j + k)->fromGate());
00827             k++;
00828         }
00829 
00830         if (tempGate == NULL)
00831             break;
00832 
00833         if (dir == OUT) {
00834             terminal->gate(gateName, j + k - 1)->disconnect();
00835             terminal->gate(gateName, j)->connectTo(tempGate);
00836         } else {
00837             tempGate->disconnect();
00838             tempGate->connectTo(terminal->gate(gateName, j));
00839         }
00840     }
00841 
00842     int nullGates = 0;
00843     for (int j = 0; j < gateArray->size(); j++)
00844         if (!terminal->gate(gateName, j)->isConnectedOutside())
00845             nullGates++;
00846 
00847     terminal->setGateSize(gateName, gateArray->size() - nullGates);
00848 }

void BaseOverlay::setReadyIcon ( bool  ready  )  [protected]

Colors module-icon blue (ready) or red (not ready).

Parameters:
ready state to visualize
00669 {
00670         bootstrapOracle->setOverlayReadyIcon(getThisNode(), ready);
00671 }

void BaseOverlay::showOverlayNeighborArrow ( const NodeHandle neighbor,
bool  flush = true,
char *  displayString = NULL 
) [protected]

Draws an arrow from this node to neighbor.

Parameters:
neighbor neighbor to point to
flush delete all previous drawn arrows starting at this node?
displayString display string to define the arrow drawing style
Todo:
add neighbor's kind to distinguish arrows pointing to the same neighbor
00675 {
00676     if (!ev.isGUI() || !drawOverlayTopology)
00677         return;
00678 
00679     char red[] = "o=red,1";
00680     if (displayString == NULL)
00681         displayString = red;
00682 
00683     cModule* neighborTerminal;
00684     cGate* neighborInGateArray;
00685 
00686     // flush
00687     if (flush) {
00688         for (int l = 0; l < thisOutGateArray->size(); l++) {
00689             cGate* tempGate
00690             = thisTerminal->gate("overlayNeighborArrowOut", l)->toGate();
00691             thisTerminal->gate("overlayNeighborArrowOut", l)->disconnect();
00692             if (tempGate != NULL)
00693                 compactGateArray(tempGate->ownerModule(), IN);
00694         }
00695         thisTerminal->setGateSize("overlayNeighborArrowOut" ,0);
00696     }
00697 
00698     int neighborModuleId;
00699     if(bootstrapOracle->getPeerInfo(neighbor) == NULL)
00700         return;
00701     else
00702         neighborModuleId = bootstrapOracle->getPeerInfo(neighbor)->getModuleID();
00703 
00704     if (simulation.module(neighborModuleId) != NULL) {
00705         neighborTerminal
00706         = simulation.module(neighborModuleId)->parentModule();
00707         neighborInGateArray = simulation.module(neighborModuleId)->
00708                               parentModule()->gate("overlayNeighborArrowIn");
00709     } else
00710         return;
00711 
00712     //if (neighborInGateArray == NULL)
00713         //return;
00714 
00715     if (thisTerminal == neighborTerminal)
00716         return;
00717 
00718     //do not draw double
00719     for (int i = 0; i < thisOutGateArray->size(); i++)
00720         if (thisTerminal->gate("overlayNeighborArrowOut", i)->toGate() != NULL
00721                 && neighborTerminal
00722                 == thisTerminal->gate("overlayNeighborArrowOut", i)->
00723                 toGate()->ownerModule())
00724             return;
00725 
00726     // IN
00727     int i = 0;
00728     if (neighborInGateArray->size() == 0) {
00729         neighborTerminal->setGateSize("overlayNeighborArrowIn", 1);
00730         }
00731     else {
00732         for (i = 0; i < neighborInGateArray->size() - 1; i++) {
00733             if (!(neighborTerminal->gate("overlayNeighborArrowIn", i)
00734                     ->isConnectedOutside()))
00735                 break;
00736         }
00737         if (neighborTerminal->gate("overlayNeighborArrowIn", i)
00738                 ->isConnectedOutside()) {
00739             neighborTerminal->setGateSize("overlayNeighborArrowIn", i + 2);
00740             i++;
00741         }
00742     }
00743 
00744     // OUT
00745     int j = 0;
00746     if (thisOutGateArray->size() == 0)
00747         thisTerminal->setGateSize("overlayNeighborArrowOut", 1);
00748     else {
00749         for (j = 0; j < (thisOutGateArray->size() - 1); j++) {
00750             if (!(thisTerminal->gate("overlayNeighborArrowOut", j)
00751                     ->isConnectedOutside()))
00752                 break;
00753         }
00754         if (thisTerminal->gate("overlayNeighborArrowOut", j)
00755                 ->isConnectedOutside()) {
00756             thisTerminal->setGateSize("overlayNeighborArrowOut", j + 2);
00757             j++;
00758         }
00759     }
00760 
00761     thisTerminal->gate("overlayNeighborArrowOut", j)->
00762     connectTo(neighborTerminal->gate("overlayNeighborArrowIn", i));
00763 
00764     thisTerminal->gate("overlayNeighborArrowOut", j)->
00765     setDisplayString(displayString);
00766 }

void BaseOverlay::deleteOverlayNeighborArrow ( const NodeHandle neighbor  )  [protected]

Removes an arrow from this node to neighbor.

Parameters:
neighbor neighbor to remove arrow to
Todo:
add neighbor's kind to distinguish arrows pointing to the same neighbor
00769 {
00770     if (!ev.isGUI() || !drawOverlayTopology)
00771         return;
00772 
00773     //does neighbor module exist anymore?
00774     int neighborModuleId;
00775     if(bootstrapOracle->getPeerInfo(neighbor) == NULL)
00776         return;
00777     else
00778         neighborModuleId = bootstrapOracle->getPeerInfo(neighbor)->getModuleID();
00779 
00780     if (simulation.module(neighborModuleId) == NULL)
00781         return;
00782 
00783     cModule* neighborTerminal
00784     = simulation.module(neighborModuleId)->parentModule();
00785 
00786     //find gate
00787     bool compactOut = false;
00788     bool compactIn = false;
00789     for (int i = 0; i < thisOutGateArray->size(); i++) {
00790         // NULL-Gate?
00791         if (thisTerminal->gate("overlayNeighborArrowOut", i)->toGate() == NULL) {
00792             compactOut = true;
00793             continue;
00794         }
00795 
00796         if (thisTerminal->gate("overlayNeighborArrowOut", i)->toGate()->ownerModule()->id() == neighborTerminal->id()) {
00797             thisTerminal->gate("overlayNeighborArrowOut", i)->disconnect();
00798             compactOut = true;
00799             compactIn = true;
00800         }
00801     }
00802 
00803     //compact OUT-array
00804     if (compactOut)
00805         compactGateArray(thisTerminal, OUT);
00806     //compact IN-array
00807     if (compactIn)
00808         compactGateArray(neighborTerminal, IN);
00809 }

void BaseOverlay::sendMessageToUDP ( const TransportAddress dest,
BaseOverlayMessage *  msg 
)

Sends message to underlay.

Parameters:
dest destination node
msg message to send
00856 {
00857     if (!iterativeLookup)
00858     {
00859         // increase HopCount on outgoing RouteMessages in recursive mode
00860         // moved here from sendToKey() so that hopCount is only increased
00861         // when the Overlay decides to actually send the Message in
00862         // forwardMessageRecursive().
00863         BaseRouteMessage* routeMsg = dynamic_cast<BaseRouteMessage*>(msg);
00864         if (routeMsg && (dest != thisNode))
00865         {
00866             routeMsg->setHopCount(routeMsg->getHopCount() + 1);
00867         }
00868     }
00869 
00870     // if there's still a control info attached to the message, remove it
00871     cPolymorphic* ctrlInfo = msg->removeControlInfo();
00872     if (ctrlInfo != NULL)
00873         delete ctrlInfo;
00874 
00875     // debug message
00876     if (debugOutput) {
00877         EV << "BaseOverlay: Node " << thisNode.ip << ": sends "
00878         << msg->name() << " to " << dest.ip << "." << endl;
00879     }
00880 
00881     msg->setKind(UDP_C_DATA);
00882     UDPControlInfo* udpControlInfo = new UDPControlInfo();
00883     udpControlInfo->setSrcAddr(thisNode.ip);
00884     udpControlInfo->setSrcPort(thisNode.port);
00885     udpControlInfo->setDestAddr(dest.ip);
00886     udpControlInfo->setDestPort(dest.port);
00887     msg->setControlInfo(udpControlInfo);
00888 
00889     send(msg, "to_udp");
00890 
00891     if (dest != thisNode) {
00892         // record statistics, if message is not local
00893         if (msg->getSignaling() == false) {
00894             RECORD_STATS(numSent++; bytesSent += msg->byteLength());
00895         } else {
00896             RECORD_STATS(numSignalingSent++; bytesSignalingSent +=
00897                              msg->byteLength());
00898         }
00899         recordOverlaySentStats(msg);
00900     }
00901 }

void BaseOverlay::pingNode ( const TransportAddress dest,
simtime_t  timeout = -1,
int  retries = 0,
const char *  caption = NULL,
RpcListener rpcListener = NULL,
int  rpcId = -1 
)

ping a node by its TransportAddress

Statistics are collected by this method.

Parameters:
dest the node to ping
timeout RPC timeout
retries how often to retry after timeout
caption special name for the ping call (instead of "PING")
rpcListener RPC Listener
rpcId RPC id
00927 {
00928     PingCall* call = createPingCall(caption);
00929     RECORD_STATS(numPingSent++; bytesPingSent += call->byteLength());
00930     sendRpcMessage(dest, call, rpcListener, OverlayKey::UNSPECIFIED_KEY,
00931             rpcId, timeout, retries);
00932 }

void BaseOverlay::pingKey ( const OverlayKey destKey,
simtime_t  timeout = -1,
int  retries = 0,
const char *  caption = NULL,
RpcListener rpcListener = NULL,
int  rpcId = -1 
)

ping a node by its OverlayKey

Statistics are collected by this method.

Parameters:
destKey key of the node to ping
timeout RPC timeout
retries how often to retry after timeout
caption special name for the ping call (instead of "PING")
rpcListener RPC Listener
rpcId RPC id
00937 {
00938     PingCall* call = createPingCall(caption);
00939     RECORD_STATS(numPingSent++; bytesPingSent += call->byteLength());
00940     sendRpcMessage(TransportAddress::UNSPECIFIED_NODE, call, rpcListener,
00941             destKey, rpcId, timeout, retries);
00942 }

void BaseOverlay::initLookups (  )  [private]

creates a LookupSet

00952 {
00953     lookups = LookupSet();
00954 }

void BaseOverlay::finishLookups (  )  [private]

deletes entries in lookups

00957 {
00958     while (lookups.size()!=0)
00959         delete *lookups.begin();
00960     lookups.clear();
00961 }

void BaseOverlay::internalRoute ( const OverlayKey key,
cMessage *  msg,
const NodeHandle hint = NodeHandle::UNSPECIFIED_NODE 
) [private]

calls route(const OverlayKey& key, cMessage* msg, const NodeHandle& hint) if useBaseLookup is false, else sendToKey(const OverlayKey& key, BaseOverlayMessage* msg, uint numNeighbors, const TransportAddress& nextHop)

01031 {
01032     // check if base lookup should be used
01033     if (!useBaseLookup) {
01034         route(key,msg,hint);
01035         return;
01036     }
01037 
01038     if(key.isUnspecified())
01039         error("route(): key unspecified!");
01040 
01041     // create base route message
01042     BaseAppDataMessage* baseAppDataMsg =
01043         new BaseAppDataMessage("BaseAppDataMessage");
01044     baseAppDataMsg->setType(APPDATA);
01045     baseAppDataMsg->setLength(BASEAPPDATA_L(baseAppDataMsg));
01046     baseAppDataMsg->setSignaling(false);
01047     //baseAppDataMsg->setKind(1);//???
01048     baseAppDataMsg->encapsulate(msg);
01049 
01050     // debug output
01051     if (debugOutput) {
01052         EV << "BaseOverlay: Node " << thisNode.ip << " received message from "
01053         "application." << endl;
01054     }
01055 
01056     sendToKey( key, baseAppDataMsg, 1, hint );
01057 }

void BaseOverlay::forwardMessageRecursive ( const TransportAddress dest,
BaseRouteMessage *  msg 
) [private, virtual]

Hook for forwarded message in recursive lookup mode.

Default implementation just calls sendMessageToUDP(). This hook can for example be used to detect failed nodes and call handleFailedNode() before the actual forwarding takes place.

Parameters:
dest destination node
msg message to send

Reimplemented in Pastry.

01061 {
01062     sendMessageToUDP(dest, msg);
01063 }

void BaseOverlay::sendToKey ( const OverlayKey key,
BaseOverlayMessage *  message,
int  numSiblings = 1,
const TransportAddress nextHop = TransportAddress::UNSPECIFIED_NODE 
)

Sends a message to an overlay node, with the generic routing algorithm.

Parameters:
key The destination key
message Message to be sent
numSiblings number of siblings to send message to (numSiblings > 1 means multicast)
nextHop If nextHop is given, the message gets sent to this node before it is routed (nextHop is used as a proxy)
01067 {
01068     BaseRouteMessage* routeMsg = NULL;
01069 
01070     if (key.isUnspecified())
01071         error("BaseOverlay::sendToKey(): unspecified destination key!");
01072 
01073     if (msg->getType() != OVERLAYROUTE) {
01074         routeMsg = new BaseRouteMessage("BaseRouteMessage");
01075         routeMsg->setType(OVERLAYROUTE);
01076         routeMsg->setDestKey(key);
01077         routeMsg->setSrcNode(thisNode);
01078         routeMsg->setSignaling(msg->getSignaling());
01079         //routeMsg->setKind(routeMsg->getSignaling() ? 0 : 1);//???
01080         routeMsg->setKind(NOT_FORWARDED);
01081         // copy the name of the inner message
01082         routeMsg->setName(msg->name());
01083         routeMsg->setLength(BASEROUTE_L(routeMsg));
01084         routeMsg->encapsulate(msg);
01085 
01086         OverlayCtrlInfo* routeCtrlInfo = new OverlayCtrlInfo;
01087         routeCtrlInfo->setLastHopAddr(thisNode.ip);
01088         routeCtrlInfo->setLastHopPort(thisNode.port);
01089 
01090         routeMsg->setControlInfo(routeCtrlInfo);
01091     } else {
01092         routeMsg = check_and_cast<BaseRouteMessage*>(msg);
01093     }
01094 
01095     if (!nextHop.isUnspecified()) {
01096         // send msg to nextHop if specified (used for join rpcs)
01097         if (iterativeLookup && (nextHop != thisNode))
01098         {
01099             routeMsg->setHopCount(routeMsg->getHopCount() + 1);
01100         }
01101         sendMessageToUDP(nextHop, routeMsg);
01102         return;
01103     }
01104 
01105     if (iterativeLookup) {
01106         // create lookup and sent to key
01107         AbstractLookup* lookup = createLookup(routeMsg);
01108         lookup->lookup( routeMsg->getDestKey(), numSiblings, hopCountMax,
01109                         new SendToKeyListener( this, routeMsg ) );
01110     } else  {
01111         NodeVector* nextHops = findNode(routeMsg->getDestKey(), 1,
01112                                         numSiblings, routeMsg);
01113         
01114         if (nextHops->size() == 0) {
01115             EV <<   "BaseOverlay::sendToKey(): findNode() returned NULL "
01116             "- dropping message" << endl;
01117             // statistics
01118             RECORD_STATS(numDropped++; bytesDropped += routeMsg->byteLength());
01119             delete routeMsg;
01120         } else {
01121             // delete message if the hop count maximum is exceeded
01122             if (routeMsg->getHopCount() >= hopCountMax) {
01123                 EV << "BaseOverlay: Node " << thisNode.ip << " discards "
01124                    << routeMsg->name() << " from "
01125                    << routeMsg->getSrcNode().ip
01126                    << ". The hop count maximum has been exceeded. ("
01127                    << routeMsg->getHopCount() << ">="
01128                    << hopCountMax << ")" << endl;
01129                 
01130                 // statistics
01131                 RECORD_STATS(numDropped++;
01132                              bytesDropped += routeMsg->byteLength());
01133                 delete routeMsg;
01134                 delete nextHops;
01135                 return;
01136             }
01137 
01138             // callForward to app
01139             if(useCommonAPIforward && !iterativeLookup
01140                && dynamic_cast<BaseAppDataMessage*>(routeMsg->encapsulatedMsg())
01141                && routeMsg->kind() != ALREADY_FORWARDED) {
01142                 //routeMsg->setKind(ALREADY_FORWARDED);
01143                 callForward(routeMsg->getDestKey(), routeMsg, (*nextHops)[0]);
01144                 delete nextHops;
01145                 return;
01146             }
01147             routeMsg->setKind(NOT_FORWARDED);
01148 
01149             // forward msg if this node is not responsible for the key
01150 
01151             if ((*nextHops)[0] != thisNode) {
01152                 OverlayCtrlInfo* overlayCtrlInfo =
01153                     dynamic_cast<OverlayCtrlInfo*>(msg->removeControlInfo());//why msg??? routeMsg???
01154 
01155                 // records statistics, if we forward this message
01156                 if ((overlayCtrlInfo != NULL) &&
01157                         (overlayCtrlInfo->getLastHopAddr() != thisNode.ip)) {
01158                     if (routeMsg->getSignaling() == false) {
01159                         RECORD_STATS(numForwarded++; bytesForwarded +=
01160                                          routeMsg->byteLength());
01161                     } else {
01162                         RECORD_STATS(numSignalingForwarded++;
01163                                      bytesSignalingForwarded +=
01164                                          routeMsg->byteLength());
01165                     }
01166                 }
01167                 if (overlayCtrlInfo != NULL)
01168                     delete overlayCtrlInfo;
01169             }
01170 
01171             bool err;
01172             if (((*nextHops)[0] == thisNode) &&
01173                 !isSiblingFor(thisNode,routeMsg->getDestKey(),
01174                                  numSiblings, &err)) {
01175                 error("nextHop = thisNode but isSiblingsFor() is false!");
01176             }
01177 
01178 //          EV << "!!!! Node " << thisNode << " forwards msg for key "
01179 //             << routeMsg->getDestKey() << " to node " << (*nextHops)[0]
01180 //             << endl;
01181 
01182             forwardMessageRecursive((*nextHops)[0], routeMsg);
01183         }
01184         delete nextHops;
01185     }
01186 }

AbstractLookup * BaseOverlay::createLookup ( const BaseOverlayMessage *  msg = NULL  )  [protected, virtual]

Creates an abstract iterative lookup instance.

Parameters:
msg pointer to the message for which the lookup is created. Derived classes can use it to construct an object with additional info for the lookup class.
Returns:
AbstractLookup* The new lookup instance.
01190 {
01191     AbstractLookup* newLookup = new BaseLookup( this, baseLookupConfig );
01192     lookups.insert( newLookup );
01193     return newLookup;
01194 }

void BaseOverlay::removeLookup ( AbstractLookup lookup  )  [protected, virtual]

Removes the abstract lookup instance.

Parameters:
lookup 
01197 {
01198     lookups.erase(lookup);
01199 }

OverlayKey BaseOverlay::distance ( const OverlayKey x,
const OverlayKey y 
) const [protected, 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:
x Left-hand-side Key
y Right-hand-side key
Returns:
OverlayKey Distance between x and y
01204 {
01205     return x > y ? x-y : y-x;
01206 }

NodeVector * BaseOverlay::findNode ( const OverlayKey key,
int  numRedundantNodes,
int  numSiblings,
BaseOverlayMessage *  msg = NULL 
) [protected, virtual]

Implements the find node call.

This method simply returns the closest nodes known in the corresponding routing topology. If the node is a sibling for this key (isSiblingFor(key) = true), this method returns all numSiblings siblings, with the closest neighbor to the key first.

Parameters:
key The lookup key.
numRedundantNodes Maximum number of next hop nodes to return.
numSiblings number of siblings to return
msg A pointer to the BaseRouteMessage or FindNodeCall message of this lookup.
Returns:
NodeVector with closest nodes.

Reimplemented in Broose, Chord, Koorde, and Pastry.

01213 {
01214     opp_error( "findNode: Not implemented!" );
01215     return NULL;
01216 }

void BaseOverlay::joinOverlay (  )  [protected, virtual]

Join the overlay with a given nodeID in thisNode.key.

Join the overlay with a given nodeID in thisNode.key. This method may be called by an application to join the overlay with a specific nodeID. It is also called if the node's IP address changes.

Reimplemented in Broose, Chord, and Pastry.

01220 {
01221     std::cout << "BaseOverlay::joinOverlay(): Not implemented!" << endl;
01222     //joinOverlay(): Not implemented
01223     return;
01224 }

bool BaseOverlay::handleFailedNode ( const TransportAddress failed  )  [protected, virtual]

Handles a failed node.

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

Parameters:
failed the failed node
Returns:
true if lookup should retry here

Reimplemented in Pastry.

01227 {
01228     return false;
01229 }

PingResponse * BaseOverlay::ping ( PingCall *  call  )  [protected, virtual]

Implements a ping call.


This method implements a simple ping call.

Parameters:
call The ping message
Returns:
The ping response or NULL if no response should be sent.
01232 {
01233     std::string pongName("PONG: ");
01234     pongName += call->name();
01235     PingResponse* response = new PingResponse(pongName.c_str());
01236 
01237     response->setLength( PINGRESPONSE_L(response) );
01238     return response;
01239 }

void BaseOverlay::lookupRpc ( LookupCall *  call  )  [protected, virtual]

01373 {
01374     // create lookup and sent to key
01375     AbstractLookup* lookup = createLookup(call);
01376     lookup->lookup( call->getKey(), call->getNumSiblings(), hopCountMax,
01377                     new SendToKeyListener( this, call ) );
01378 }

void BaseOverlay::countFindNodeCall ( const FindNodeCall *  call  )  [protected]

01286 {
01287     RECORD_STATS(numFindNodeSent++;
01288             bytesFindNodeSent += call->byteLength());
01289 }

void BaseOverlay::countFailedNodeCall ( const FailedNodeCall *  call  )  [protected]

01292 {
01293     RECORD_STATS(numFailedNodeSent++;
01294             bytesFailedNodeSent += call->byteLength());
01295 }

void BaseOverlay::sendRpcMessageToDestination ( int  destType,
const TransportAddress dest,
const OverlayKey destKey,
BaseOverlayMessage *  message 
) [protected, virtual]

Reimplemented from BaseRpc.

01250 {
01251     switch(destType) {
01252       case RPC_TO_UDP:
01253           sendMessageToUDP( dest, message );
01254           break;
01255       case RPC_TO_KEY:
01256           sendToKey( destKey, message, 1, dest );
01257           break;
01258       case RPC_TO_UPPERTIER:
01259           send( message, "to_app");
01260           break;
01261       case RPC_TO_LOWERTIER:
01262           break;
01263     }
01264 }  

bool BaseOverlay::internalHandleRpc ( BaseCallMessage *  msg  )  [protected, virtual]

Handles internal rpc requests.


This method is used to implement basic functionionality in the BaseRpc.

Parameters:
msg The call message
Returns:
bool true, if call has been handled.

Reimplemented from BaseRpc.

01268 {
01269     // call rpc stubs
01270     RPC_SWITCH_START( msg );
01271     RPC_DELEGATE( Ping, pingRpc );
01272     RPC_DELEGATE( FindNode, findNodeRpc );
01273     RPC_DELEGATE( FailedNode, failedNodeRpc );
01274     RPC_DELEGATE( Lookup, lookupRpc );
01275     RPC_SWITCH_END( );
01276 
01277     // check if rpc has been handled
01278     IF_RPC_HANDLED return true;
01279     else
01280         return false;
01281 }

void BaseOverlay::findNodeRpc ( FindNodeCall *  call  )  [private]

01299 {
01300     // if this node is malicious don't answer a findNodeCall
01301     if (isMalicious()) {
01302         EV << "BaseOverlay: Node ignores findNodeCall "
01303            << "because this node is malicious!" << endl;
01304         delete call;
01305         return;
01306     }
01307 
01308     FindNodeResponse* findNodeResponse =
01309         new FindNodeResponse("FindNodeResponse");
01310 
01311     NodeVector* nextHops = findNode(call->getLookupKey(),
01312                                     call->getNumRedundantNodes(),
01313                                     call->getNumSiblings(), call);
01314 
01315     findNodeResponse->setClosestNodesArraySize(nextHops->size());
01316 
01317     for (uint i=0; i < nextHops->size(); i++) {
01318         findNodeResponse->setClosestNodes(i, (*nextHops)[i]);
01319     }
01320 
01321     bool err;
01322     if (isSiblingFor(thisNode, call->getLookupKey(), call->getNumSiblings(),
01323                         &err)) {
01324         findNodeResponse->setSiblings(true);
01325     }
01326 
01327     findNodeResponse->setLength(FINDNODERESPONSE_L(findNodeResponse));
01328 
01329     if (call->hasObject("findNodeExt")) {
01330         cMessage* findNodeExt = (cMessage*)call->removeObject("findNodeExt");
01331         findNodeResponse->addObject(findNodeExt);
01332         findNodeResponse->addLength(findNodeExt->length());
01333     }
01334 
01335     RECORD_STATS(numFindNodeResponseSent++; bytesFindNodeResponseSent +=
01336                  findNodeResponse->byteLength());
01337 
01338     delete nextHops;
01339 
01340     sendRpcResponse( call, findNodeResponse );
01341 }

void BaseOverlay::failedNodeRpc ( FailedNodeCall *  call  )  [private]

01344 {
01345     FailedNodeResponse* failedNodeResponse =
01346         new FailedNodeResponse("FailedNodeResponse");
01347     failedNodeResponse->setTryAgain(handleFailedNode(call->getFailedNode()));
01348     failedNodeResponse->setLength(FAILEDNODERESPONSE_L(failedNodeResponse));
01349     if (call->hasObject("findNodeExt"))
01350     {
01351         cMessage* findNodeExt = check_and_cast<cMessage*>(
01352                 call->removeObject("findNodeExt"));
01353         failedNodeResponse->addObject(findNodeExt);
01354         failedNodeResponse->addLength(findNodeExt->length());
01355     }
01356 
01357     RECORD_STATS(numFailedNodeResponseSent++; bytesFailedNodeResponseSent +=
01358             failedNodeResponse->byteLength());
01359 
01360     sendRpcResponse( call, failedNodeResponse );
01361 }

void BaseOverlay::pingRpc ( PingCall *  call  )  [private]

01365 {
01366     PingResponse* response = ping(call);
01367     RECORD_STATS(numPingResponseSent++; bytesPingResponseSent +=
01368             response->byteLength());
01369     sendRpcResponse( call, response );
01370 }

PingCall * BaseOverlay::createPingCall ( const char *  caption  )  [private]

00910 {
00911     PingCall* call;
00912     if ( caption )
00913     {
00914         call = new PingCall(caption);
00915     }
00916     else
00917     {
00918         call = new PingCall("PING");
00919     }
00920     call->setLength(PINGCALL_L(call));
00921     return call;
00922 }


Friends And Related Function Documentation

friend class BaseLookup [friend]

friend class BasePathLookup [friend]


Member Data Documentation

int BaseOverlay::numSent [private]

int BaseOverlay::bytesSent [private]

int BaseOverlay::numSignalingSent [private]

int BaseOverlay::bytesSignalingSent [private]

int BaseOverlay::numReceived [private]

int BaseOverlay::bytesReceived [private]

int BaseOverlay::numSignalingReceived [private]

int BaseOverlay::bytesSignalingReceived [private]

int BaseOverlay::numForwarded [protected]

int BaseOverlay::bytesForwarded [protected]

int BaseOverlay::numSignalingForwarded [protected]

int BaseOverlay::bytesSignalingForwarded [protected]

int BaseOverlay::numPingSent [protected]

int BaseOverlay::bytesPingSent [protected]

int BaseOverlay::numPingResponseSent [protected]

int BaseOverlay::bytesPingResponseSent [protected]

int BaseOverlay::numFindNodeSent [protected]

int BaseOverlay::bytesFindNodeSent [protected]

int BaseOverlay::numFindNodeResponseSent [protected]

int BaseOverlay::bytesFindNodeResponseSent [protected]

int BaseOverlay::numFailedNodeSent [protected]

int BaseOverlay::bytesFailedNodeSent [protected]

int BaseOverlay::numFailedNodeResponseSent [protected]

int BaseOverlay::bytesFailedNodeResponseSent [protected]

simtime_t BaseOverlay::creationTime [protected]

cModule* BaseOverlay::thisTerminal [protected]

BootstrapOracle* BaseOverlay::bootstrapOracle [protected]

GlobalStatistics* BaseOverlay::globalStatistics [protected]

NotificationBoard* BaseOverlay::notificationBoard [protected]

UnderlayConfigurator* BaseOverlay::underlayConfigurator [protected]

bool BaseOverlay::debugOutput [protected]

Reimplemented from BaseRpc.

bool BaseOverlay::measureNetwInitPhase [protected]

bool BaseOverlay::onlyCommonAPIMessages [protected]

bool BaseOverlay::useBaseLookup [protected]

bool BaseOverlay::iterativeLookup [protected]

bool BaseOverlay::useCommonAPIforward [protected]

int BaseOverlay::localPort [protected]

int BaseOverlay::hopCountMax [protected]

int BaseOverlay::numDropped [protected]

int BaseOverlay::bytesDropped [protected]

cOutVector BaseOverlay::delayVector [protected]

cOutVector BaseOverlay::hopCountVector [protected]

cGate* BaseOverlay::thisOutGateArray [private]

cGate* BaseOverlay::thisInGateArray [private]

bool BaseOverlay::drawOverlayTopology [private]

BaseLookupConfiguration BaseOverlay::baseLookupConfig [protected]

LookupSet BaseOverlay::lookups [protected]


The documentation for this class was generated from the following files:
Generated on Tue Jul 24 16:51:18 2007 for ITM OverSim by  doxygen 1.5.1