#include <BaseOverlay.h>
Inheritance diagram for BaseOverlay:
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.
Public Member Functions | ||||
virtual | ~BaseOverlay () | |||
Virtual destructor. | ||||
bool | isMalicious () | |||
Returns true, if node is malicious. | ||||
NodeHandle & | getThisNode () | |||
Returns the NodeHandle of this node. | ||||
void | join (const OverlayKey &nodeID=OverlayKey::UNSPECIFIED_KEY) | |||
Join the overlay with a given nodeID. | ||||
virtual NodeVector * | local_lookup (const OverlayKey &key, int num, bool safe) | |||
finds nodes closest to the given OverlayKey | ||||
virtual NodeVector * | neighborSet (int 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 AbstractLookup * | createLookup (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 NodeVector * | findNode (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 | |||
BootstrapOracle * | bootstrapOracle | |||
GlobalStatistics * | globalStatistics | |||
NotificationBoard * | notificationBoard | |||
UnderlayConfigurator * | underlayConfigurator | |||
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 |
typedef hash_set<AbstractLookup*, lookupHashFcn, lookupHashFcn> BaseOverlay::LookupSet [protected] |
enum BaseOverlay::Direction [private] |
BaseOverlay::~BaseOverlay | ( | ) | [virtual] |
void BaseOverlay::initialize | ( | int | stage | ) | [private] |
initializes base-class-attributes
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] |
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.
stage | the init stage |
Reimplemented in Broose, Chord, Gia, Koorde, Pastry, and Vast.
void BaseOverlay::finishOverlay | ( | ) | [protected, virtual] |
bool BaseOverlay::isMalicious | ( | ) |
Returns true, if node is malicious.
00254 { 00255 return bootstrapOracle->isMalicious(getThisNode()); 00256 }
NodeHandle & BaseOverlay::getThisNode | ( | ) |
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.
key | destination key | |
msg | message to route | |
hint | next hop (usually unused) |
Reimplemented in Gia.
void BaseOverlay::callDeliver | ( | BaseOverlayMessage * | msg, | |
const OverlayKey & | destKey | |||
) | [protected] |
Calls deliver function in application.
Encapsulates messages in KBRdeliver messages and sends them to application.
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
.
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
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.
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.
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] |
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.
node | the NodeHandle | |
key | destination key | |
numSiblings | The nodes knows all numSiblings nodes close to this key | |
err | return false if the range could not be determined |
Reimplemented 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.
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().
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().
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.
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] |
void BaseOverlay::handleTimerEvent | ( | cMessage * | msg | ) | [protected, virtual] |
void BaseOverlay::handleAppMessage | ( | cMessage * | msg | ) | [protected, virtual] |
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.
msg | The overlay message to be sent to the UDP layer |
Reimplemented in Broose, Chord, and Koorde.
void BaseOverlay::compactGateArray | ( | cModule * | terminal, | |
enum Direction | dir | |||
) | [private] |
compacts arrow gate-array
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).
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.
neighbor | neighbor to point to | |
flush | delete all previous drawn arrows starting at this node? | |
displayString | display string to define the arrow drawing style |
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.
neighbor | neighbor to remove arrow to |
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.
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.
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.
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] |
void BaseOverlay::finishLookups | ( | ) | [private] |
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.
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.
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.
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. |
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.
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).
x | Left-hand-side Key | |
y | Right-hand-side key |
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.
key | The lookup key. | |
numRedundantNodes | Maximum number of next hop nodes to return. | |
numSiblings | number of siblings to return | |
msg | A pointer to the BaseRouteMessage or FindNodeCall message of this lookup. |
Reimplemented in Broose, Chord, Koorde, and Pastry.
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.
failed | the failed node |
Reimplemented in Pastry.
PingResponse * BaseOverlay::ping | ( | PingCall * | call | ) | [protected, virtual] |
Implements a ping call.
This method implements a simple ping call.
call | The ping message |
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.
msg | The call message |
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] |
friend class BaseLookup [friend] |
friend class BasePathLookup [friend] |
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] |