#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 | |
BaseOverlay () | |
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 TransportAddress &hint=TransportAddress::UNSPECIFIED_NODE) |
Routes message through overlay. | |
virtual void | route_direct (const TransportAddress &dest, cMessage *msg) |
Route a application message directly to a transport address. | |
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 | receiveChangeNotification (int category, cPolymorphic *details) |
callback-method for events at the NotificationBoard | |
virtual void | handleTransportAddressChangedNotification () |
This method gets call if the node has a new TransportAddress (IP address) because he changed his access network. | |
virtual void | handleNodeLeaveNotification () |
This method gets call **.gracefulLeaveDelay seconds before it is killed. | |
virtual void | handleNodeGracefulLeaveNotification () |
This method gets call **.gracefulLeaveDelay seconds before it is killed if this node is among the gracefulLeaveProbability nodes. | |
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 TransportAddress &hint=TransportAddress::UNSPECIFIED_NODE) |
calls route(const OverlayKey& key, cMessage* msg, const TransportAddress& 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 |
class | SendToKeyListener |
Classes | |
class | lookupHashFcn |
typedef hash_set<AbstractLookup*, lookupHashFcn, lookupHashFcn> BaseOverlay::LookupSet [protected] |
enum BaseOverlay::Direction [private] |
BaseOverlay::BaseOverlay | ( | ) |
00049 { 00050 bootstrapOracle = NULL; 00051 underlayConfigurator = NULL; 00052 globalStatistics = NULL; 00053 notificationBoard = NULL; 00054 thisTerminal = NULL; 00055 }
BaseOverlay::~BaseOverlay | ( | ) | [virtual] |
void BaseOverlay::initialize | ( | int | stage | ) | [private] |
initializes base-class-attributes
stage | the init stage |
00069 { 00070 if(stage == MIN_STAGE_OVERLAY) { 00071 OverlayKey::setKeyLength(par("keyLength")); 00072 00073 // fetch some parameters 00074 debugOutput = par("debugOutput"); 00075 measureNetwInitPhase = par("measureNetwInitPhase"); 00076 localPort = par("localPort"); 00077 hopCountMax = par("hopCountMax"); 00078 drawOverlayTopology = par("drawOverlayTopology"); 00079 useBaseLookup = par("useBaseLookup"); 00080 iterativeLookup = par("iterativeLookup"); 00081 useCommonAPIforward = false; 00082 onlyCommonAPIMessages = true; 00083 00084 // set base lookup parameters 00085 baseLookupConfig.redundantNodes = par("lookupRedundantNodes"); 00086 baseLookupConfig.parallelPaths = par("lookupParallelPaths"); 00087 baseLookupConfig.parallelRpcs = par("lookupParallelRpcs"); 00088 baseLookupConfig.secure = par("lookupSecure"); 00089 baseLookupConfig.merge = par("lookupMerge"); 00090 baseLookupConfig.failedNodeRpcs = par("lookupFailedNodeRpcs"); 00091 00092 // statistics 00093 numSent = 0; 00094 bytesSent = 0; 00095 numSignalingSent = 0; 00096 bytesSignalingSent = 0; 00097 numReceived = 0; 00098 bytesReceived = 0; 00099 numSignalingReceived = 0; 00100 bytesSignalingReceived = 0; 00101 numForwarded = 0; 00102 bytesForwarded = 0; 00103 numSignalingForwarded = 0; 00104 bytesSignalingForwarded = 0; 00105 numDropped = 0; 00106 bytesDropped = 0; 00107 numPingSent = 0; 00108 bytesPingSent = 0; 00109 numPingResponseSent = 0; 00110 bytesPingResponseSent = 0; 00111 numFindNodeSent = 0; 00112 bytesFindNodeSent = 0; 00113 numFindNodeResponseSent = 0; 00114 bytesFindNodeResponseSent = 0; 00115 numFailedNodeSent = 0; 00116 bytesFailedNodeSent = 0; 00117 numFailedNodeResponseSent = 0; 00118 bytesFailedNodeResponseSent = 0; 00119 00120 WATCH(numSent); 00121 WATCH(bytesSent); 00122 WATCH(numSignalingSent); 00123 WATCH(bytesSignalingSent); 00124 WATCH(numReceived); 00125 WATCH(bytesReceived); 00126 WATCH(numSignalingReceived); 00127 WATCH(bytesSignalingReceived); 00128 WATCH(numForwarded); 00129 WATCH(bytesForwarded); 00130 WATCH(numSignalingForwarded); 00131 WATCH(bytesSignalingForwarded); 00132 WATCH(numDropped); 00133 WATCH(bytesDropped); 00134 WATCH(numPingSent); 00135 WATCH(bytesPingSent); 00136 WATCH(numPingResponseSent); 00137 WATCH(bytesPingResponseSent); 00138 WATCH(numFindNodeSent); 00139 WATCH(bytesFindNodeSent); 00140 WATCH(numFindNodeResponseSent); 00141 WATCH(bytesFindNodeResponseSent); 00142 WATCH(numFailedNodeSent); 00143 WATCH(bytesFailedNodeSent); 00144 WATCH(numFailedNodeResponseSent); 00145 WATCH(bytesFailedNodeResponseSent); 00146 00147 // set up UDP 00148 bindToPort(localPort); 00149 00150 // find friend modules 00151 bootstrapOracle = BootstrapOracleAccess().get(); 00152 underlayConfigurator = UnderlayConfiguratorAccess().get(); 00153 globalStatistics = GlobalStatisticsAccess().get(); 00154 notificationBoard = NotificationBoardAccess().get(); 00155 00156 thisTerminal = parentModule()->parentModule(); 00157 00158 // set up local nodehandle 00159 //thisNode.moduleId = parentModule()->id(); 00160 thisNode.ip = IPAddressResolver(). 00161 addressOf(parentModule()->parentModule()).get4(); 00162 thisNode.port = localPort; 00163 thisNode.key = OverlayKey::UNSPECIFIED_KEY; 00164 00165 // set up arrow-gates 00166 thisOutGateArray = thisTerminal->gate("overlayNeighborArrowOut"); 00167 thisInGateArray = thisTerminal->gate("overlayNeighborArrowIn"); 00168 thisTerminal->setGateSize("overlayNeighborArrowOut" ,1); 00169 thisTerminal->setGateSize("overlayNeighborArrowIn" ,1); 00170 00171 // subscribe to the notification board 00172 notificationBoard->subscribe(this, NF_OVERLAY_TRANSPORTADDRESS_CHANGED); 00173 notificationBoard->subscribe(this, NF_OVERLAY_NODE_LEAVE); 00174 notificationBoard->subscribe(this, NF_OVERLAY_NODE_GRACEFUL_LEAVE); 00175 00176 // init rpcs 00177 initRpcs(); 00178 initLookups(); 00179 00180 // statistics 00181 globalStatistics->nodesInitialized++; 00182 creationTime = simTime(); 00183 } 00184 00185 00186 if (stage >= MIN_STAGE_OVERLAY && stage <= MAX_STAGE_OVERLAY) 00187 initializeOverlay(stage); 00188 00189 if (stage == MAX_STAGE_OVERLAY) { 00190 // setReadyIcon(false); 00191 if ((bool)par("joinOnApplicationRequest") == false) { 00192 join(); 00193 } 00194 } 00195 }
void BaseOverlay::finish | ( | ) | [private] |
collects statistical data
00203 { 00204 finishOverlay(); 00205 00206 globalStatistics->nodesFinished++; 00207 00208 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00209 if(time == 0) return; 00210 00211 globalStatistics->addStdDev("BaseOverlay: Sent User Messages/s", numSent / time); 00212 globalStatistics->addStdDev("BaseOverlay: Sent User Bytes/s", bytesSent / time); 00213 globalStatistics->addStdDev("BaseOverlay: Sent Signaling Messages/s", numSignalingSent / time); 00214 globalStatistics->addStdDev("BaseOverlay: Sent Signaling Bytes/s", bytesSignalingSent / time); 00215 globalStatistics->addStdDev("BaseOverlay: Sent Total Messages/s", (numSent + numSignalingSent)/time); 00216 globalStatistics->addStdDev("BaseOverlay: Sent Total Bytes/s", (bytesSent + bytesSignalingSent)/time); 00217 globalStatistics->addStdDev("BaseOverlay: Sent FindNode Messages/s", numFindNodeSent / time); 00218 globalStatistics->addStdDev("BaseOverlay: Sent FindNode Bytes/s", bytesFindNodeSent / time); 00219 00220 globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Messages/s", numFindNodeResponseSent / time); 00221 globalStatistics->addStdDev("BaseOverlay: Sent FindNodeResponse Bytes/s", bytesFindNodeResponseSent / time); 00222 globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Messages/s", numFailedNodeSent / time); 00223 globalStatistics->addStdDev("BaseOverlay: Sent FailedNode Bytes/s", bytesFailedNodeSent / time); 00224 globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Messages/s", numFailedNodeResponseSent / time); 00225 globalStatistics->addStdDev("BaseOverlay: Sent FailedNodeResponse Bytes/s", bytesFailedNodeResponseSent / time); 00226 00227 globalStatistics->addStdDev("BaseOverlay: Received User Messages/s", numReceived / time); 00228 globalStatistics->addStdDev("BaseOverlay: Received User Bytes/s", bytesReceived / time); 00229 globalStatistics->addStdDev("BaseOverlay: Received Signaling Messages/s", numSignalingReceived / time); 00230 globalStatistics->addStdDev("BaseOverlay: Received Signaling Bytes/s", bytesSignalingReceived / time); 00231 globalStatistics->addStdDev("BaseOverlay: Received Total Messages/s", 00232 (numReceived + numSignalingReceived)/time); 00233 globalStatistics->addStdDev("BaseOverlay: Received Total Bytes/s", 00234 (bytesReceived + bytesSignalingReceived)/time); 00235 globalStatistics->addStdDev("BaseOverlay: Forwarded User Messages/s", numForwarded / time); 00236 globalStatistics->addStdDev("BaseOverlay: Forwarded User Bytes/s", bytesForwarded / time); 00237 globalStatistics->addStdDev("BaseOverlay: Forwarded Signaling Messages/s", numSignalingForwarded / time); 00238 globalStatistics->addStdDev("BaseOverlay: Forwarded Signaling Bytes/s", bytesSignalingForwarded / time); 00239 globalStatistics->addStdDev("BaseOverlay: Forwarded Total Messages/s", 00240 (numForwarded + numSignalingForwarded)/time); 00241 globalStatistics->addStdDev("BaseOverlay: Forwarded Total Bytes/s", 00242 (bytesForwarded + bytesSignalingForwarded)/time); 00243 00244 globalStatistics->addStdDev("BaseOverlay: Dropped Messages/s", numDropped / time); 00245 globalStatistics->addStdDev("BaseOverlay: Dropped Bytes/s", bytesDropped / time); 00246 00247 globalStatistics->addStdDev("BaseOverlay: Active Time", simTime() - creationTime); 00248 00249 globalStatistics->doFinish(); 00250 00251 }
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.
00262 { 00263 return bootstrapOracle->isMalicious(getThisNode()); 00264 }
NodeHandle & BaseOverlay::getThisNode | ( | ) |
Returns the NodeHandle of this node.
00267 { 00268 return thisNode; 00269 }
void BaseOverlay::bindToPort | ( | int | port | ) | [protected, virtual] |
Tells UDP we want to get all packets arriving on the given port.
00275 { 00276 cModule *node = parentModule()->parentModule(); 00277 IPvXAddress ip = IPAddressResolver().addressOf(node); 00278 00279 EV << "[BaseOverlay::bindToPort() @ " << ip 00280 << " (" << thisNode.key.toString(16) << ")]\n" 00281 << " Binding to UDP port " << port 00282 << endl; 00283 00284 // TODO UDPAppBase should be ported to use UDPSocket sometime, but for now 00285 // we just manage the UDP socket by hand... 00286 cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND); 00287 UDPControlInfo *ctrl = new UDPControlInfo(); 00288 ctrl->setSrcPort(port); 00289 ctrl->setSockId(UDPSocket::generateSocketId()); 00290 msg->setControlInfo(ctrl); 00291 send(msg, "to_udp"); 00292 }
void BaseOverlay::sendToUDP | ( | cMessage * | msg, | |
int | srcPort, | |||
const IPvXAddress & | destAddr, | |||
int | destPort | |||
) | [protected, virtual] |
Sends a packet over UDP.
00296 { 00297 // send message to UDP, with the appropriate control info attached 00298 msg->setKind(UDP_C_DATA); 00299 00300 UDPControlInfo *ctrl = new UDPControlInfo(); 00301 ctrl->setSrcPort(srcPort); 00302 ctrl->setDestAddr(destAddr); 00303 ctrl->setDestPort(destPort); 00304 msg->setControlInfo(ctrl); 00305 00306 cModule *node = parentModule(); 00307 IPvXAddress ip = IPAddressResolver().addressOf(node); 00308 EV << "[BaseOverlay::sendToUDP() @ " << ip 00309 << " (" << thisNode.key.toString(16) << ")]\n" 00310 << " Sending packet: " << msg 00311 << endl; 00312 printPacket(msg); 00313 00314 send(msg, "to_udp"); 00315 }
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).
00318 { 00319 UDPControlInfo *ctrl = check_and_cast<UDPControlInfo *>(msg->controlInfo()); 00320 00321 IPvXAddress srcAddr = ctrl->srcAddr(); 00322 IPvXAddress destAddr = ctrl->destAddr(); 00323 int srcPort = ctrl->srcPort(); 00324 int destPort = ctrl->destPort(); 00325 00326 ev << "[BaseOverlay::printPacket() @ " << thisNode.ip 00327 << " (" << thisNode.key.toString(16) << ")]\n" 00328 << " " << msg << " (" << msg->byteLength() << " bytes) \n" 00329 << " " << srcAddr << " :" << srcPort << " --> " << destAddr << ":" << destPort 00330 << endl; 00331 }
void BaseOverlay::route | ( | const OverlayKey & | key, | |
cMessage * | msg, | |||
const TransportAddress & | hint = TransportAddress::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::route_direct | ( | const TransportAddress & | dest, | |
cMessage * | msg | |||
) | [protected, virtual] |
Route a application message directly to a transport address.
The default implementation encapsulates the given message msg in a BaseAppMessage and sends it directly to the given TransportAddress dest.
dest | destination transport address | |
msg | message to route |
01136 { 01137 if (dest.isUnspecified()) 01138 error("route_direct(): destination unspecified!"); 01139 01140 // create base route message 01141 BaseAppDataMessage* baseAppDataMsg = 01142 new BaseAppDataMessage("BaseAppDataMessage"); 01143 baseAppDataMsg->setType(APPDATA); 01144 baseAppDataMsg->setLength(BASEAPPDATA_L(baseAppDataMsg)); 01145 baseAppDataMsg->setSignaling(false); 01146 //baseAppDataMsg->setKind(1);//??? 01147 baseAppDataMsg->encapsulate(msg); 01148 01149 // debug output 01150 if (debugOutput) { 01151 EV << "[BaseOverlay::route_direct() @ " << thisNode.ip 01152 << " (" << thisNode.key.toString(16) << ")]\n" 01153 << " Received message from application" 01154 << endl; 01155 } 01156 01157 sendMessageToUDP(dest, baseAppDataMsg); 01158 }
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 | |
destKey | the destination key of the message |
00346 { 00347 KBRdeliver* deliverMsg = new KBRdeliver(); 00348 00349 OverlayCtrlInfo* overlayCtrlInfo = 00350 check_and_cast<OverlayCtrlInfo*> 00351 (msg->removeControlInfo()); 00352 00353 deliverMsg->setControlInfo(overlayCtrlInfo); 00354 deliverMsg->setDestKey(destKey); 00355 00356 deliverMsg->encapsulate(msg->decapsulate()); 00357 00358 deliverMsg->setType(KBR_DELIVER); 00359 00360 send(deliverMsg, "to_app"); 00361 00362 delete msg; 00363 }
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 |
00367 { 00368 KBRforward* forwardMsg = new KBRforward(); 00369 00370 forwardMsg->setDestKey(msg->getDestKey()); 00371 forwardMsg->setNextHopNode(nextHopNode); 00372 forwardMsg->encapsulate(msg->encapsulatedMsg()->decapsulate()); 00373 00374 OverlayCtrlInfo* overlayCtrlInfo = 00375 new OverlayCtrlInfo(); 00376 //overlayCtrlInfo->setThisNode(thisNode); 00377 overlayCtrlInfo->setHopCount(msg->getHopCount()); 00378 overlayCtrlInfo->setSrcNode(msg->getSrcNode()); 00379 00380 if(msg->controlInfo() != NULL) { 00381 OverlayCtrlInfo* ctrlInfo = 00382 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo()); 00383 overlayCtrlInfo->setLastHopAddr(ctrlInfo->getLastHopAddr()); 00384 overlayCtrlInfo->setLastHopPort(ctrlInfo->getLastHopPort()); 00385 00386 delete ctrlInfo; 00387 } 00388 00389 forwardMsg->setControlInfo(overlayCtrlInfo); 00390 00391 forwardMsg->setType(KBR_FORWARD); 00392 00393 send(forwardMsg, "to_app"); 00394 00395 delete msg; 00396 }
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? |
00443 { 00444 KBRupdate* updateMsg = new KBRupdate("UPDATE"); 00445 00446 updateMsg->setNode(node); 00447 updateMsg->setJoined(joined); 00448 00449 updateMsg->setType(KBR_UPDATE); 00450 00451 send(updateMsg, "to_app");//"to_upperTier"); 00452 }
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. |
00416 { 00417 Enter_Method("join()"); 00418 00419 // set nodeID and IP 00420 thisNode.ip = 00421 IPAddressResolver().addressOf(parentModule()->parentModule()).get4(); 00422 if (nodeID.isUnspecified()) { 00423 thisNode.key = OverlayKey::random(); 00424 } else { 00425 thisNode.key = nodeID; 00426 } 00427 00428 callUpdate(thisNode, true); 00429 00430 joinOverlay(); 00431 }
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 | The safe parameters is not implemented yet |
00400 { 00401 Enter_Method("local_lookup()"); 00402 00403 if (safe == true) { 00404 error("BaseOverlay::local_lookup(): safe flag is not implemented!"); 00405 } 00406 00407 NodeVector* nodeVector = findNode(key, num, num); 00408 00409 if(((int)nodeVector->size()) > num) 00410 nodeVector->resize(num); 00411 00412 return nodeVector; 00413 }
NodeVector * BaseOverlay::neighborSet | ( | int | num | ) | [virtual] |
00435 { 00436 Enter_Method("neighborSet()"); 00437 00438 return local_lookup(thisNode.key, num, false); 00439 }
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.
00456 { 00457 Enter_Method("isSiblingFor()"); 00458 00459 opp_error( "isSiblingFor: Not implemented!" ); 00460 00461 return false; 00462 }
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.
00465 { 00466 Enter_Method("getMaxNumSiblings()"); 00467 00468 opp_error( "getMaxNumSiblings: Not implemented!" ); 00469 00470 return false; 00471 }
int BaseOverlay::getMaxNumRedundantNodes | ( | ) | [virtual] |
Query the maximum number of redundant next hop nodes that are returned by findNode().
Reimplemented in Broose, Chord, and Pastry.
00474 { 00475 Enter_Method("getMaxNumRedundantNodes()"); 00476 00477 opp_error( "getMaxNumRedundantNodes: Not implemented!" ); 00478 00479 return false; 00480 }
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 |
00489 { 00490 // process self-messages 00491 if (msg->isSelfMessage()) { 00492 // process rpc self-messages 00493 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg); 00494 if (rpcMessage!=NULL) { 00495 internalHandleRpcMessage(rpcMessage); 00496 return; 00497 } 00498 // process all other self-messages 00499 handleTimerEvent(msg); 00500 } 00501 00502 // process messages from UDP 00503 else if (msg->arrivedOn("from_udp")) { 00504 UDPControlInfo* udpControlInfo = 00505 check_and_cast<UDPControlInfo*>(msg->removeControlInfo()); 00506 OverlayCtrlInfo* overlayCtrlInfo = new OverlayCtrlInfo; 00507 overlayCtrlInfo->setLastHopAddr(udpControlInfo->srcAddr()); 00508 overlayCtrlInfo->setLastHopPort(udpControlInfo->srcPort()); 00509 msg->setControlInfo(overlayCtrlInfo); 00510 delete udpControlInfo; 00511 00512 BaseOverlayMessage* baseOverlayMsg = 00513 dynamic_cast<BaseOverlayMessage*>(msg); 00514 00515 if (baseOverlayMsg == NULL) { 00516 delete msg; 00517 return; 00518 } 00519 00520 // records stats if message is not a UDP "self message" 00521 if (overlayCtrlInfo->getLastHopAddr() != thisNode.ip) { 00522 if (baseOverlayMsg->getSignaling() == false) 00523 RECORD_STATS(numReceived++; bytesReceived += 00524 baseOverlayMsg->byteLength()); 00525 else 00526 RECORD_STATS(numSignalingReceived++;bytesSignalingReceived 00527 += baseOverlayMsg->byteLength()); 00528 } 00529 00530 handleBaseOverlayMessage(baseOverlayMsg); 00531 } 00532 00533 // process CommonAPIMessages from App 00534 else if (dynamic_cast<CommonAPIMessage*>(msg) != NULL) { 00535 if (dynamic_cast<KBRroute*>(msg) != NULL) { 00536 KBRroute* apiMsg = dynamic_cast<KBRroute*>(msg); 00537 00538 internalRoute(apiMsg->getDestKey(), apiMsg->decapsulate(), 00539 apiMsg->getHint()); 00540 } else if (dynamic_cast<KBRrouteDirect*>(msg) != NULL) { 00541 KBRrouteDirect* apiMsg = dynamic_cast<KBRrouteDirect*>(msg); 00542 00543 route_direct(apiMsg->getDest(), apiMsg->decapsulate()); 00544 } else if (dynamic_cast<KBRforward*>(msg) != NULL) { 00545 KBRforward* apiMsg = dynamic_cast<KBRforward*>(msg); 00546 OverlayCtrlInfo* overlayCtrlInfo = 00547 check_and_cast<OverlayCtrlInfo*> 00548 (msg->removeControlInfo()); 00549 00550 BaseAppDataMessage* dataMsg = 00551 new BaseAppDataMessage(); 00552 dataMsg->setType(APPDATA); 00553 dataMsg->setLength(BASEAPPDATA_L(dataMsg)); 00554 dataMsg->setName(msg->encapsulatedMsg()->name()); 00555 dataMsg->encapsulate(msg->decapsulate()); 00556 dataMsg->setSignaling(false); 00557 00558 BaseRouteMessage* routeMsg = new BaseRouteMessage(dataMsg->name()); 00559 routeMsg->setType(OVERLAYROUTE); 00560 routeMsg->setLength(BASEROUTE_L(routeMsg)); 00561 routeMsg->encapsulate(dataMsg); 00562 00563 routeMsg->setSignaling(false); 00564 routeMsg->setDestKey(apiMsg->getDestKey()); 00565 routeMsg->setSrcNode(overlayCtrlInfo->getSrcNode()); 00566 routeMsg->setHopCount(overlayCtrlInfo->getHopCount()); 00567 routeMsg->setControlInfo(overlayCtrlInfo); 00568 00569 routeMsg->setKind(ALREADY_FORWARDED); 00570 00571 sendToKey(apiMsg->getDestKey(), routeMsg, 1, apiMsg->getNextHopNode()); 00572 } 00573 00574 delete msg; 00575 } 00576 00577 else if (dynamic_cast<BaseRpcMessage*>(msg) != NULL) { 00578 BaseRpcMessage* rpcMessage = 00579 dynamic_cast<BaseRpcMessage*>(msg); 00580 internalHandleRpcMessage(rpcMessage); 00581 } 00582 00583 // process other messages from App 00584 else if (msg->arrivedOn("from_app") && onlyCommonAPIMessages == false) 00585 handleAppMessage(msg); 00586 00587 else { 00588 opp_error("BaseOverlay::handleMessage(): Received msg with " 00589 "unknown type!"); 00590 // RECORD_STATS(numDropped++; bytesDropped += msg->byteLength()); 00591 delete msg; 00592 } 00593 }
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 | |
destKey | the destination key of the message |
00597 { 00598 switch(msg->getType()) { 00599 case OVERLAYSIGNALING: 00600 handleUDPMessage(msg); 00601 return; 00602 00603 case RPC: { 00604 // process rpc-messages 00605 BaseRpcMessage* rpcMessage = 00606 check_and_cast<BaseRpcMessage*>(msg); 00607 internalHandleRpcMessage(rpcMessage); 00608 return; 00609 } 00610 00611 case APPDATA: { 00612 BaseAppDataMessage* baseAppDataMsg = 00613 check_and_cast<BaseAppDataMessage*>(msg); 00614 callDeliver(baseAppDataMsg, destKey); 00615 return; 00616 } 00617 00618 case OVERLAYROUTE: { 00619 BaseRouteMessage* baseRouteMsg = 00620 check_and_cast<BaseRouteMessage*>(msg); 00621 00622 if (baseRouteMsg->getDestKey().isUnspecified()) 00623 opp_error("BaseOverlay: No destination key in ROUTE msg"); 00624 00625 00626 // if this node is malicious drop the message 00627 if (isMalicious()) { 00628 EV << "[BaseOverlay::handleBaseOverlayMessage() @ " << thisNode.ip 00629 << " (" << thisNode.key.toString(16) << ")]\n" 00630 << " BaseRouteMessage gets dropped because this node is malicious" 00631 << endl; 00632 RECORD_STATS(numDropped++; 00633 bytesDropped += baseRouteMsg->byteLength()); 00634 delete msg; 00635 return; 00636 } 00637 00638 bool err; 00639 if (isSiblingFor(thisNode, baseRouteMsg->getDestKey(), 00640 1, &err)) { 00641 OverlayCtrlInfo* overlayCtrlInfo = 00642 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo()); 00643 00644 overlayCtrlInfo->setHopCount(baseRouteMsg->getHopCount()); 00645 overlayCtrlInfo->setSrcNode(baseRouteMsg->getSrcNode()); 00646 00647 BaseOverlayMessage* tmpMsg 00648 = check_and_cast<BaseOverlayMessage*> 00649 (baseRouteMsg->decapsulate()); 00650 tmpMsg->setControlInfo(overlayCtrlInfo); 00651 00652 handleBaseOverlayMessage(tmpMsg, baseRouteMsg->getDestKey());//bh 00653 delete msg; 00654 return; 00655 } else { 00656 // forward msg if this node is not responsible for the key 00657 sendToKey(baseRouteMsg->getDestKey(), baseRouteMsg, 1); 00658 return; 00659 } 00660 break; 00661 } 00662 00663 default: 00664 EV << "[BaseOverlay::handleBaseOverlayMessage() @ " << thisNode.ip 00665 << " (" << thisNode.key.toString(16) << ")]\n" 00666 << " Received unknown message from UDP of type " << msg->name() 00667 << endl; 00668 break; 00669 } 00670 }
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::receiveChangeNotification | ( | int | category, | |
cPolymorphic * | details | |||
) | [protected, virtual] |
callback-method for events at the NotificationBoard
category | ... TODO ... | |
details | ... TODO ... |
Reimplemented in Vast.
00673 { 00674 Enter_Method_Silent(); 00675 if (category == NF_OVERLAY_TRANSPORTADDRESS_CHANGED) { 00676 handleTransportAddressChangedNotification(); 00677 } else if (category == NF_OVERLAY_NODE_LEAVE) { 00678 handleNodeLeaveNotification(); 00679 } else if (category == NF_OVERLAY_TRANSPORTADDRESS_CHANGED) { 00680 handleNodeGracefulLeaveNotification(); 00681 } 00682 }
void BaseOverlay::handleTransportAddressChangedNotification | ( | ) | [protected, virtual] |
This method gets call if the node has a new TransportAddress (IP address) because he changed his access network.
00685 { 00686 // get new ip address 00687 thisNode.ip = IPAddressResolver().addressOf( 00688 parentModule()->parentModule()).get4(); 00689 00690 joinOverlay(); 00691 }
void BaseOverlay::handleNodeLeaveNotification | ( | ) | [protected, virtual] |
void BaseOverlay::handleNodeGracefulLeaveNotification | ( | ) | [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? |
00859 { 00860 cGate* gateArray = (dir == OUT ? terminal->gate("overlayNeighborArrowOut") 00861 : terminal->gate("overlayNeighborArrowIn")); 00862 const char* gateName = (dir == OUT ? "overlayNeighborArrowOut" 00863 : "overlayNeighborArrowIn"); 00864 00865 for (int j = 0; j < gateArray->size() - 1; j++) { 00866 if (terminal->gate(gateName, j)->isConnectedOutside()) 00867 continue; 00868 00869 cGate* tempGate = NULL; 00870 int k = 1; 00871 while ((tempGate == NULL) && ((j + k) != gateArray->size())) { 00872 tempGate = (dir == OUT ? terminal->gate(gateName, j + k)->toGate() 00873 : terminal->gate(gateName, j + k)->fromGate()); 00874 k++; 00875 } 00876 00877 if (tempGate == NULL) 00878 break; 00879 00880 if (dir == OUT) { 00881 terminal->gate(gateName, j + k - 1)->disconnect(); 00882 terminal->gate(gateName, j)->connectTo(tempGate); 00883 } else { 00884 tempGate->disconnect(); 00885 tempGate->connectTo(terminal->gate(gateName, j)); 00886 } 00887 } 00888 00889 int nullGates = 0; 00890 for (int j = 0; j < gateArray->size(); j++) 00891 if (!terminal->gate(gateName, j)->isConnectedOutside()) 00892 nullGates++; 00893 00894 terminal->setGateSize(gateName, gateArray->size() - nullGates); 00895 }
void BaseOverlay::setReadyIcon | ( | bool | ready | ) | [protected] |
Colors module-icon blue (ready) or red (not ready).
ready | state to visualize |
00728 { 00729 displayString().setTagArg("i", 1, ready ? "" : "red"); 00730 bootstrapOracle->setOverlayReadyIcon(getThisNode(), ready); 00731 }
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 |
00735 { 00736 if (!ev.isGUI() || !drawOverlayTopology) 00737 return; 00738 00739 char red[] = "o=red,1"; 00740 if (displayString == NULL) 00741 displayString = red; 00742 00743 cModule* neighborTerminal; 00744 cGate* neighborInGateArray; 00745 00746 // flush 00747 if (flush) { 00748 for (int l = 0; l < thisOutGateArray->size(); l++) { 00749 cGate* tempGate 00750 = thisTerminal->gate("overlayNeighborArrowOut", l)->toGate(); 00751 thisTerminal->gate("overlayNeighborArrowOut", l)->disconnect(); 00752 if (tempGate != NULL) 00753 compactGateArray(tempGate->ownerModule(), IN); 00754 } 00755 thisTerminal->setGateSize("overlayNeighborArrowOut" ,0); 00756 } 00757 00758 if(bootstrapOracle->getPeerInfo(neighbor) == NULL) 00759 return; 00760 00761 neighborTerminal = simulation.module(bootstrapOracle 00762 ->getPeerInfo(neighbor)->getModuleID()); 00763 if (neighborTerminal != NULL) { 00764 neighborInGateArray = neighborTerminal->gate("overlayNeighborArrowIn"); 00765 } else 00766 return; 00767 00768 if (thisTerminal == neighborTerminal) 00769 return; 00770 00771 //do not draw double 00772 for (int i = 0; i < thisOutGateArray->size(); i++) 00773 if (thisTerminal->gate("overlayNeighborArrowOut", i)->toGate() != NULL 00774 && neighborTerminal 00775 == thisTerminal->gate("overlayNeighborArrowOut", i)-> 00776 toGate()->ownerModule()) 00777 return; 00778 00779 // IN 00780 int i = 0; 00781 if (neighborInGateArray->size() == 0) { 00782 neighborTerminal->setGateSize("overlayNeighborArrowIn", 1); 00783 } 00784 else { 00785 for (i = 0; i < neighborInGateArray->size() - 1; i++) { 00786 if (!(neighborTerminal->gate("overlayNeighborArrowIn", i) 00787 ->isConnectedOutside())) 00788 break; 00789 } 00790 if (neighborTerminal->gate("overlayNeighborArrowIn", i) 00791 ->isConnectedOutside()) { 00792 neighborTerminal->setGateSize("overlayNeighborArrowIn", i + 2); 00793 i++; 00794 } 00795 } 00796 00797 // OUT 00798 int j = 0; 00799 if (thisOutGateArray->size() == 0) 00800 thisTerminal->setGateSize("overlayNeighborArrowOut", 1); 00801 else { 00802 for (j = 0; j < (thisOutGateArray->size() - 1); j++) { 00803 if (!(thisTerminal->gate("overlayNeighborArrowOut", j) 00804 ->isConnectedOutside())) 00805 break; 00806 } 00807 if (thisTerminal->gate("overlayNeighborArrowOut", j) 00808 ->isConnectedOutside()) { 00809 thisTerminal->setGateSize("overlayNeighborArrowOut", j + 2); 00810 j++; 00811 } 00812 } 00813 00814 thisTerminal->gate("overlayNeighborArrowOut", j)-> 00815 connectTo(neighborTerminal->gate("overlayNeighborArrowIn", i)); 00816 00817 thisTerminal->gate("overlayNeighborArrowOut", j)-> 00818 setDisplayString(displayString); 00819 }
void BaseOverlay::deleteOverlayNeighborArrow | ( | const NodeHandle & | neighbor | ) | [protected] |
Removes an arrow from this node to neighbor.
neighbor | neighbor to remove arrow to |
00822 { 00823 if (!ev.isGUI() || !drawOverlayTopology) 00824 return; 00825 00826 cModule* neighborTerminal = simulation.module(bootstrapOracle 00827 ->getPeerInfo(neighbor)->getModuleID()); 00828 00829 if (neighborTerminal == NULL) 00830 return; 00831 00832 //find gate 00833 bool compactOut = false; 00834 bool compactIn = false; 00835 for (int i = 0; i < thisOutGateArray->size(); i++) { 00836 // NULL-Gate? 00837 if (thisTerminal->gate("overlayNeighborArrowOut", i)->toGate() == NULL) { 00838 compactOut = true; 00839 continue; 00840 } 00841 00842 if (thisTerminal->gate("overlayNeighborArrowOut", i) 00843 ->toGate()->ownerModule()->id() == neighborTerminal->id()) { 00844 thisTerminal->gate("overlayNeighborArrowOut", i)->disconnect(); 00845 compactOut = true; 00846 compactIn = true; 00847 } 00848 } 00849 00850 //compact OUT-array 00851 if (compactOut) 00852 compactGateArray(thisTerminal, OUT); 00853 //compact IN-array 00854 if (compactIn) 00855 compactGateArray(neighborTerminal, IN); 00856 }
void BaseOverlay::sendMessageToUDP | ( | const TransportAddress & | dest, | |
BaseOverlayMessage * | msg | |||
) |
Sends message to underlay.
dest | destination node | |
msg | message to send |
00903 { 00904 if (!iterativeLookup) 00905 { 00906 // increase HopCount on outgoing RouteMessages in recursive mode 00907 // moved here from sendToKey() so that hopCount is only increased 00908 // when the Overlay decides to actually send the Message in 00909 // forwardMessageRecursive(). 00910 BaseRouteMessage* routeMsg = dynamic_cast<BaseRouteMessage*>(msg); 00911 if (routeMsg && (dest != thisNode)) 00912 { 00913 routeMsg->setHopCount(routeMsg->getHopCount() + 1); 00914 } 00915 } 00916 00917 // if there's still a control info attached to the message, remove it 00918 cPolymorphic* ctrlInfo = msg->removeControlInfo(); 00919 if (ctrlInfo != NULL) 00920 delete ctrlInfo; 00921 00922 // debug message 00923 if (debugOutput) { 00924 EV << "[BaseOverlay::sendMessageToUDP() @ " << thisNode.ip 00925 << " (" << thisNode.key.toString(16) << ")]\n" 00926 << " Sending" << msg->name() << " to " << dest.ip 00927 << endl; 00928 } 00929 00930 msg->setKind(UDP_C_DATA); 00931 UDPControlInfo* udpControlInfo = new UDPControlInfo(); 00932 udpControlInfo->setSrcAddr(thisNode.ip); 00933 udpControlInfo->setSrcPort(thisNode.port); 00934 udpControlInfo->setDestAddr(dest.ip); 00935 udpControlInfo->setDestPort(dest.port); 00936 msg->setControlInfo(udpControlInfo); 00937 00938 send(msg, "to_udp"); 00939 00940 if (dest != thisNode) { 00941 // record statistics, if message is not local 00942 if (msg->getSignaling() == false) { 00943 RECORD_STATS(numSent++; bytesSent += msg->byteLength()); 00944 } else { 00945 RECORD_STATS(numSignalingSent++; bytesSignalingSent += 00946 msg->byteLength()); 00947 } 00948 recordOverlaySentStats(msg); 00949 } 00950 }
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 |
00976 { 00977 PingCall* call = createPingCall(caption); 00978 RECORD_STATS(numPingSent++; bytesPingSent += call->byteLength()); 00979 sendRpcMessage(dest, call, rpcListener, OverlayKey::UNSPECIFIED_KEY, 00980 rpcId, timeout, retries); 00981 }
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 |
00986 { 00987 PingCall* call = createPingCall(caption); 00988 RECORD_STATS(numPingSent++; bytesPingSent += call->byteLength()); 00989 sendRpcMessage(TransportAddress::UNSPECIFIED_NODE, call, rpcListener, 00990 destKey, rpcId, timeout, retries); 00991 }
void BaseOverlay::initLookups | ( | ) | [private] |
void BaseOverlay::finishLookups | ( | ) | [private] |
void BaseOverlay::internalRoute | ( | const OverlayKey & | key, | |
cMessage * | msg, | |||
const TransportAddress & | hint = TransportAddress::UNSPECIFIED_NODE | |||
) | [private] |
calls route(const OverlayKey& key, cMessage* msg, const TransportAddress& hint) if useBaseLookup is false, else sendToKey(const OverlayKey& key, BaseOverlayMessage* msg, uint numNeighbors, const TransportAddress& nextHop)
01105 { 01106 // check if base lookup should be used 01107 if (!useBaseLookup) { 01108 route(key,msg,hint); 01109 return; 01110 } 01111 01112 if(key.isUnspecified()) 01113 error("route(): key unspecified!"); 01114 01115 // create base route message 01116 BaseAppDataMessage* baseAppDataMsg = 01117 new BaseAppDataMessage("BaseAppDataMessage"); 01118 baseAppDataMsg->setType(APPDATA); 01119 baseAppDataMsg->setLength(BASEAPPDATA_L(baseAppDataMsg)); 01120 baseAppDataMsg->setSignaling(false); 01121 //baseAppDataMsg->setKind(1);//??? 01122 baseAppDataMsg->encapsulate(msg); 01123 01124 // debug output 01125 if (debugOutput) { 01126 EV << "[BaseOverlay::internalRoute() @ " << thisNode.ip 01127 << " (" << thisNode.key.toString(16) << ")]\n" 01128 << " Received message from application" 01129 << endl; 01130 } 01131 01132 sendToKey( key, baseAppDataMsg, 1, hint ); 01133 }
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.
01163 { 01164 sendMessageToUDP(dest, msg); 01165 }
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) |
01169 { 01170 BaseRouteMessage* routeMsg = NULL; 01171 01172 if (key.isUnspecified()) 01173 error("BaseOverlay::sendToKey(): unspecified destination key!"); 01174 01175 if (msg->getType() != OVERLAYROUTE) { 01176 routeMsg = new BaseRouteMessage("BaseRouteMessage"); 01177 routeMsg->setType(OVERLAYROUTE); 01178 routeMsg->setDestKey(key); 01179 routeMsg->setSrcNode(thisNode); 01180 routeMsg->setSignaling(msg->getSignaling()); 01181 //routeMsg->setKind(routeMsg->getSignaling() ? 0 : 1);//??? 01182 routeMsg->setKind(NOT_FORWARDED); 01183 // copy the name of the inner message 01184 routeMsg->setName(msg->name()); 01185 routeMsg->setLength(BASEROUTE_L(routeMsg)); 01186 routeMsg->encapsulate(msg); 01187 01188 OverlayCtrlInfo* routeCtrlInfo = new OverlayCtrlInfo; 01189 routeCtrlInfo->setLastHopAddr(thisNode.ip); 01190 routeCtrlInfo->setLastHopPort(thisNode.port); 01191 01192 routeMsg->setControlInfo(routeCtrlInfo); 01193 } else { 01194 routeMsg = check_and_cast<BaseRouteMessage*>(msg); 01195 } 01196 01197 if (!nextHop.isUnspecified()) { 01198 // send msg to nextHop if specified (used for join rpcs) 01199 if (iterativeLookup && (nextHop != thisNode)) 01200 { 01201 routeMsg->setHopCount(routeMsg->getHopCount() + 1); 01202 } 01203 sendMessageToUDP(nextHop, routeMsg); 01204 return; 01205 } 01206 01207 if (iterativeLookup) { 01208 // create lookup and sent to key 01209 AbstractLookup* lookup = createLookup(routeMsg); 01210 lookup->lookup( routeMsg->getDestKey(), numSiblings, hopCountMax, 01211 0, new SendToKeyListener( this, routeMsg )); 01212 } else { 01213 NodeVector* nextHops = findNode(routeMsg->getDestKey(), 1, 01214 numSiblings, routeMsg); 01215 01216 if (nextHops->size() == 0) { 01217 EV << "[BaseOverlay::sendToKey() @ " << thisNode.ip 01218 << " (" << thisNode.key.toString(16) << ")]\n" 01219 << " FindNode() returned NULL - dropping message" 01220 << endl; 01221 // statistics 01222 RECORD_STATS(numDropped++; bytesDropped += routeMsg->byteLength()); 01223 delete routeMsg; 01224 } else { 01225 // delete message if the hop count maximum is exceeded 01226 if (routeMsg->getHopCount() >= hopCountMax) { 01227 01228 EV << "[BaseOverlay::sendToKey() @ " << thisNode.ip 01229 << " (" << thisNode.key.toString(16) << ")]\n" 01230 << " Discards " << routeMsg->name() << " from " 01231 << routeMsg->getSrcNode().ip << "\n" 01232 << " The hop count maximum has been exceeded (" 01233 << routeMsg->getHopCount() << ">=" 01234 << hopCountMax << ")" 01235 << endl; 01236 // statistics 01237 RECORD_STATS(numDropped++; 01238 bytesDropped += routeMsg->byteLength()); 01239 delete routeMsg; 01240 delete nextHops; 01241 return; 01242 } 01243 01244 // callForward to app 01245 if(useCommonAPIforward && !iterativeLookup 01246 && dynamic_cast<BaseAppDataMessage*>(routeMsg->encapsulatedMsg()) 01247 && routeMsg->kind() != ALREADY_FORWARDED) { 01248 //routeMsg->setKind(ALREADY_FORWARDED); 01249 callForward(routeMsg->getDestKey(), routeMsg, (*nextHops)[0]); 01250 delete nextHops; 01251 return; 01252 } 01253 routeMsg->setKind(NOT_FORWARDED); 01254 01255 // forward msg if this node is not responsible for the key 01256 01257 if ((*nextHops)[0] != thisNode) { 01258 OverlayCtrlInfo* overlayCtrlInfo = 01259 dynamic_cast<OverlayCtrlInfo*>(msg->removeControlInfo());//why msg??? routeMsg??? 01260 01261 // records statistics, if we forward this message 01262 if ((overlayCtrlInfo != NULL) && 01263 (overlayCtrlInfo->getLastHopAddr() != thisNode.ip)) { 01264 if (routeMsg->getSignaling() == false) { 01265 RECORD_STATS(numForwarded++; bytesForwarded += 01266 routeMsg->byteLength()); 01267 } else { 01268 RECORD_STATS(numSignalingForwarded++; 01269 bytesSignalingForwarded += 01270 routeMsg->byteLength()); 01271 } 01272 } 01273 if (overlayCtrlInfo != NULL) 01274 delete overlayCtrlInfo; 01275 } 01276 01277 bool err; 01278 if (((*nextHops)[0] == thisNode) && 01279 !isSiblingFor(thisNode,routeMsg->getDestKey(), 01280 numSiblings, &err)) { 01281 error("nextHop = thisNode but isSiblingsFor() is false!"); 01282 } 01283 01284 // EV << "[BaseOverlay::sendToKey() @ " << thisNode.ip 01285 // << " (" << thisNode.key.toString(16) << ")]\n" 01286 // << " Forwards msg for key " << routeMsg->getDestKey() "\n" 01287 // << " to node " << (*nextHops)[0] 01288 // << endl; 01289 01290 forwardMessageRecursive((*nextHops)[0], routeMsg); 01291 } 01292 delete nextHops; 01293 } 01294 }
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. |
01298 { 01299 AbstractLookup* newLookup = new BaseLookup( this, baseLookupConfig ); 01300 lookups.insert( newLookup ); 01301 return newLookup; 01302 }
void BaseOverlay::removeLookup | ( | AbstractLookup * | lookup | ) | [protected, virtual] |
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 |
01312 { 01313 // return x > y ? x-y : y-x; 01314 opp_error("BaseOverlay::distance(): Not implemented!"); 01315 return OverlayKey::UNSPECIFIED_KEY; 01316 }
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.
01330 { 01331 // std::cout << "BaseOverlay::joinOverlay(): Not implemented!" << endl; 01332 return; 01333 }
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 |
01341 { 01342 std::string pongName("PONG: "); 01343 pongName += call->name(); 01344 PingResponse* response = new PingResponse(pongName.c_str()); 01345 01346 response->setLength( PINGRESPONSE_L(response) ); 01347 return response; 01348 }
void BaseOverlay::lookupRpc | ( | LookupCall * | call | ) | [protected, virtual] |
01484 { 01485 // std::cout << simulation.simTime() << ": LookupCall " 01486 // << call->getNonce() 01487 // << " started" << endl; 01488 01489 01490 // create lookup and sent to key 01491 AbstractLookup* lookup = createLookup(call); 01492 lookup->lookup( call->getKey(), call->getNumSiblings(), hopCountMax, 01493 1, new SendToKeyListener( this, call )); 01494 }
void BaseOverlay::countFindNodeCall | ( | const FindNodeCall * | call | ) | [protected] |
01395 { 01396 RECORD_STATS(numFindNodeSent++; 01397 bytesFindNodeSent += call->byteLength()); 01398 }
void BaseOverlay::countFailedNodeCall | ( | const FailedNodeCall * | call | ) | [protected] |
01401 { 01402 RECORD_STATS(numFailedNodeSent++; 01403 bytesFailedNodeSent += call->byteLength()); 01404 }
void BaseOverlay::sendRpcMessageToDestination | ( | int | destType, | |
const TransportAddress & | dest, | |||
const OverlayKey & | destKey, | |||
BaseOverlayMessage * | message | |||
) | [protected, virtual] |
Reimplemented from BaseRpc.
01359 { 01360 switch(destType) { 01361 case RPC_TO_UDP: 01362 sendMessageToUDP( dest, message ); 01363 break; 01364 case RPC_TO_KEY: 01365 sendToKey( destKey, message, 1, dest ); 01366 break; 01367 case RPC_TO_UPPERTIER: 01368 send( message, "to_app"); 01369 break; 01370 case RPC_TO_LOWERTIER: 01371 break; 01372 } 01373 }
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.
01377 { 01378 // call rpc stubs 01379 RPC_SWITCH_START( msg ); 01380 RPC_DELEGATE( Ping, pingRpc ); 01381 RPC_DELEGATE( FindNode, findNodeRpc ); 01382 RPC_DELEGATE( FailedNode, failedNodeRpc ); 01383 RPC_DELEGATE( Lookup, lookupRpc ); 01384 RPC_SWITCH_END( ); 01385 01386 // check if rpc has been handled 01387 IF_RPC_HANDLED return true; 01388 else 01389 return false; 01390 }
void BaseOverlay::findNodeRpc | ( | FindNodeCall * | call | ) | [private] |
01408 { 01409 // if this node is malicious don't answer a findNodeCall 01410 if (isMalicious()) { 01411 EV << "[BaseOverlay::findNodeRpc() @ " << thisNode.ip 01412 << " (" << thisNode.key.toString(16) << ")]\n" 01413 << " Node ignores findNodeCall because this node is malicious" 01414 << endl; 01415 delete call; 01416 return; 01417 } 01418 01419 FindNodeResponse* findNodeResponse = 01420 new FindNodeResponse("FindNodeResponse"); 01421 01422 NodeVector* nextHops = findNode(call->getLookupKey(), 01423 call->getNumRedundantNodes(), 01424 call->getNumSiblings(), call); 01425 01426 findNodeResponse->setClosestNodesArraySize(nextHops->size()); 01427 01428 for (uint i=0; i < nextHops->size(); i++) { 01429 findNodeResponse->setClosestNodes(i, (*nextHops)[i]); 01430 } 01431 01432 bool err; 01433 if (isSiblingFor(thisNode, call->getLookupKey(), call->getNumSiblings(), 01434 &err)) { 01435 findNodeResponse->setSiblings(true); 01436 } 01437 01438 findNodeResponse->setLength(FINDNODERESPONSE_L(findNodeResponse)); 01439 01440 if (call->hasObject("findNodeExt")) { 01441 cMessage* findNodeExt = (cMessage*)call->removeObject("findNodeExt"); 01442 findNodeResponse->addObject(findNodeExt); 01443 findNodeResponse->addLength(findNodeExt->length()); 01444 } 01445 01446 RECORD_STATS(numFindNodeResponseSent++; bytesFindNodeResponseSent += 01447 findNodeResponse->byteLength()); 01448 01449 delete nextHops; 01450 01451 sendRpcResponse( call, findNodeResponse ); 01452 }
void BaseOverlay::failedNodeRpc | ( | FailedNodeCall * | call | ) | [private] |
01455 { 01456 FailedNodeResponse* failedNodeResponse = 01457 new FailedNodeResponse("FailedNodeResponse"); 01458 failedNodeResponse->setTryAgain(handleFailedNode(call->getFailedNode())); 01459 failedNodeResponse->setLength(FAILEDNODERESPONSE_L(failedNodeResponse)); 01460 if (call->hasObject("findNodeExt")) 01461 { 01462 cMessage* findNodeExt = check_and_cast<cMessage*>( 01463 call->removeObject("findNodeExt")); 01464 failedNodeResponse->addObject(findNodeExt); 01465 failedNodeResponse->addLength(findNodeExt->length()); 01466 } 01467 01468 RECORD_STATS(numFailedNodeResponseSent++; bytesFailedNodeResponseSent += 01469 failedNodeResponse->byteLength()); 01470 01471 sendRpcResponse( call, failedNodeResponse ); 01472 }
void BaseOverlay::pingRpc | ( | PingCall * | call | ) | [private] |
01476 { 01477 PingResponse* response = ping(call); 01478 RECORD_STATS(numPingResponseSent++; bytesPingResponseSent += 01479 response->byteLength()); 01480 sendRpcResponse( call, response ); 01481 }
PingCall * BaseOverlay::createPingCall | ( | const char * | caption | ) | [private] |
friend class BaseLookup [friend] |
friend class BasePathLookup [friend] |
friend class SendToKeyListener [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] |