InetUnderlayConfigurator Class Reference

Configurator module for the InetUnderlay. More...

#include <InetUnderlayConfigurator.h>

Inheritance diagram for InetUnderlayConfigurator:
UnderlayConfigurator

List of all members.

Public Member Functions

TransportAddresscreateNode (NodeType type, bool initialize=false)
 Creates an overlay node.
void preKillNode (NodeType type, TransportAddress *addr=NULL)
 Notifies and schedules overlay nodes for removal.
void migrateNode (NodeType type, TransportAddress *addr=NULL)
 Migrates overlay nodes from one access net to another.

Protected Member Functions

void initializeUnderlay (int stage)
 Sets up backbone, assigns ip addresses, calculates routing tables, sets some parameters and adds the initial number of nodes to the network.
void handleTimerEvent (cMessage *msg)
 process timer messages
void finishUnderlay ()
 Saves statistics, prints simulation time.
void setDisplayString ()
 Updates the statistics display string.

Protected Attributes

std::vector< cModule * > accessNode
 stores accessRouter
std::deque< IPvXAddress > killList
 stores nodes scheduled to be killed
std::set< int > scheduledID
 stores nodeIds to prevent migration of prekilled nodes
int numCreated
 number of overall created overlay terminals
int numKilled
 number of overall killed overlay terminals

Private Attributes

int accessRouterNum
 number of access router
int overlayAccessRouterNum
 number of overlayAccessRouter
int overlayTerminalNum
 number of terminal in the overlay

Detailed Description

Configurator module for the InetUnderlay.

Author:
Markus Mauch
Todo:
possibility to disable tier1-3 in overlay(access)routers

Definition at line 41 of file InetUnderlayConfigurator.h.


Member Function Documentation

TransportAddress * InetUnderlayConfigurator::createNode ( NodeType  type,
bool  initialize = false 
) [virtual]

Creates an overlay node.

Parameters:
type the NodeType of the node to create
initialize creation during init phase?

Implements UnderlayConfigurator.

Definition at line 233 of file InetUnderlayConfigurator.cc.

00234 {
00235     Enter_Method_Silent();
00236     // derive overlay node from ned
00237     std::string nameStr = "overlayTerminal";
00238     if( churnGenerator.size() > 1 ){
00239         nameStr += "-" + convertToString<uint32_t>(type.typeID);
00240     }
00241     cModuleType* moduleType = cModuleType::get(type.terminalType.c_str());
00242     cModule* node = moduleType->create(nameStr.c_str(), getParentModule(),
00243                                        numCreated + 1, numCreated);
00244 
00245     if (type.channelTypesTx.size() > 0) {
00246         throw cRuntimeError("InetUnderlayConfigurator::createNode(): Setting "
00247                     "channel types via the churn generator is not allowed "
00248                     "with the InetUnderlay. Use **.accessNet.channelTypes instead!");
00249     }
00250 
00251     node->par("overlayType").setStringValue(type.overlayType.c_str());
00252     node->par("tier1Type").setStringValue(type.tier1Type.c_str());
00253     node->par("tier2Type").setStringValue(type.tier2Type.c_str());
00254     node->par("tier3Type").setStringValue(type.tier3Type.c_str());
00255 
00256     node->setGateSize("pppg", 1);
00257 
00258     std::string displayString;
00259 
00260     if ((type.typeID > 1) && (type.typeID <= (NUM_COLORS + 1))) {
00261         ((displayString += "i=device/wifilaptop_l,")
00262                         += colorNames[type.typeID - 2])
00263                         += ",40;i2=block/circle_s";
00264     } else {
00265         displayString = "i=device/wifilaptop_l;i2=block/circle_s";
00266     }
00267 
00268     node->finalizeParameters();
00269     node->setDisplayString(displayString.c_str());
00270 
00271     node->buildInside();
00272     node->scheduleStart(simTime());
00273 
00274     // create meta information
00275     InetInfo* info = new InetInfo(type.typeID, node->getId(), type.context);
00276     AccessNet* accessNet= check_and_cast<AccessNet*>
00277         (accessNode[intuniform(0, accessNode.size() - 1)]
00278                 ->getSubmodule("accessNet"));
00279     info->setAccessNetModule(accessNet);
00280     // add node to a randomly chosen access net
00281     info->setNodeID(accessNet->addOverlayNode(node));
00282 
00283     // add node to bootstrap oracle
00284     globalNodeList->addPeer(IPAddressResolver().addressOf(node), info);
00285 
00286     // if the node was not created during startup we have to
00287     // finish the initialization process manually
00288     if (!initialize) {
00289         for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) {
00290             node->callInitialize(i);
00291         }
00292     }
00293 
00294     overlayTerminalCount++;
00295     numCreated++;
00296 
00297     churnGenerator[type.typeID - 1]->terminalCount++;
00298 
00299     TransportAddress *address = new TransportAddress(
00300                                        IPAddressResolver().addressOf(node));
00301 
00302     // update display
00303     setDisplayString();
00304 
00305     return address;
00306 }

void InetUnderlayConfigurator::finishUnderlay (  )  [protected, virtual]

Saves statistics, prints simulation time.

Reimplemented from UnderlayConfigurator.

Definition at line 475 of file InetUnderlayConfigurator.cc.

00476 {
00477     // statistics
00478     recordScalar("Terminals added", numCreated);
00479     recordScalar("Terminals removed", numKilled);
00480 
00481     if (!isInInitPhase()) {
00482         struct timeval now, diff;
00483         gettimeofday(&now, NULL);
00484         timersub(&now, &initFinishedTime, &diff);
00485         printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
00486     }
00487 }

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

process timer messages

Parameters:
msg the received message

Reimplemented from UnderlayConfigurator.

Definition at line 434 of file InetUnderlayConfigurator.cc.

00435 {
00436     Enter_Method_Silent();
00437 
00438     // get next scheduled node from the kill list
00439     IPvXAddress addr = killList.back();
00440     killList.pop_back();
00441 
00442     AccessNet* accessNetModule = NULL;
00443     int nodeID = -1;
00444 
00445     InetInfo* info = dynamic_cast<InetInfo*>(globalNodeList->getPeerInfo(addr));
00446     if(info != NULL) {
00447         accessNetModule = info->getAccessNetModule();
00448         nodeID = info->getNodeID();
00449     } else {
00450         opp_error("IPv4UnderlayConfigurator: Trying to kill node with nonexistant TransportAddress!");
00451     }
00452 
00453     scheduledID.erase(nodeID);
00454     globalNodeList->killPeer(addr);
00455 
00456     cModule* node = accessNetModule->removeOverlayNode(nodeID);
00457 
00458     if(node == NULL)
00459         opp_error("IPv4UnderlayConfigurator: Trying to remove node which is nonexistant in AccessNet!");
00460 
00461     node->callFinish();
00462     node->deleteModule();
00463 
00464     delete msg;
00465 }

void InetUnderlayConfigurator::initializeUnderlay ( int  stage  )  [protected, virtual]

Sets up backbone, assigns ip addresses, calculates routing tables, sets some parameters and adds the initial number of nodes to the network.

Parameters:
stage the phase of the initialisation

Implements UnderlayConfigurator.

Definition at line 41 of file InetUnderlayConfigurator.cc.

00042 {
00043     //backbone configuration
00044     if (stage == MIN_STAGE_UNDERLAY) {
00045         // Find all router modules.
00046         cTopology topo("topo");
00047         topo.extractByProperty("node");
00048 
00049         // Assign IP addresses to all router modules.
00050         std::vector<uint32> nodeAddresses;
00051         nodeAddresses.resize(topo.getNumNodes());
00052 
00053         // IP addresses for backbone
00054         // Take start IP from config file
00055         // FIXME: Make Netmask for Routers configurable!
00056         uint32 lowIPBoundary = IPAddress(par("startIP").stringValue()).getInt();
00057 
00058         // uint32 lowIPBoundary = uint32((1 << 24) + 1);
00059         int numIPNodes = 0;
00060 
00061         for (int i = 0; i < topo.getNumNodes(); i++) {
00062             ++numIPNodes;
00063 
00064             uint32 addr = lowIPBoundary + uint32(numIPNodes << 16);
00065             nodeAddresses[i] = addr;
00066 
00067             // update ip display string
00068             if (ev.isGUI()) {
00069                 topo.getNode(i)->getModule()->getDisplayString().insertTag("t", 0);
00070                 topo.getNode(i)->getModule()->getDisplayString().setTagArg("t", 0,
00071                                         const_cast<char*>(IPAddress(addr).str().c_str()));
00072                 topo.getNode(i)->getModule()->getDisplayString().setTagArg("t", 1, "l");
00073                 topo.getNode(i)->getModule()->getDisplayString().setTagArg("t", 2, "red");
00074             }
00075 
00076             // find interface table and assign address to all (non-loopback) interfaces
00077             IInterfaceTable* ift = IPAddressResolver().interfaceTableOf(topo.getNode(i)->getModule());
00078 
00079             for ( int k = 0; k < ift->getNumInterfaces(); k++ ) {
00080                 InterfaceEntry* ie = ift->getInterface(k);
00081                 if (!ie->isLoopback()) {
00082                     ie->ipv4Data()->setIPAddress(IPAddress(addr));
00083                     // full address must match for local delivery
00084                     ie->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);
00085                 }
00086             }
00087         }
00088 
00089         // Fill in routing tables.
00090         for (int i = 0; i < topo.getNumNodes(); i++) {
00091             cTopology::Node* destNode = topo.getNode(i);
00092             uint32 destAddr = nodeAddresses[i];
00093 
00094             // calculate shortest paths from everywhere towards destNode
00095             topo.calculateUnweightedSingleShortestPathsTo(destNode);
00096 
00097             // add overlayAccessRouters and overlayBackboneRouters
00098             // to the GlobalNodeList
00099             if ((strcmp(destNode->getModule()->getName(), "overlayBackboneRouter") == 0) ||
00100                     (strcmp(destNode->getModule()->getName(), "overlayAccessRouter") == 0)) {
00101                 //add node to bootstrap oracle
00102                 PeerInfo* info = new PeerInfo(0, destNode->getModule()->getId(), NULL);
00103                 globalNodeList->addPeer(IPvXAddress(nodeAddresses[i]), info);
00104             }
00105 
00106 
00107             // If destNode is the outRouter, add a default route
00108             // to outside network via the TunOutDevice and a route to the
00109             // Gateway
00110             if ( strcmp(destNode->getModule()->getName(), "outRouter" ) == 0 ) {
00111                 IPRoute* defRoute = new IPRoute();
00112                 defRoute->setHost(IPAddress::UNSPECIFIED_ADDRESS);
00113                 defRoute->setNetmask(IPAddress::UNSPECIFIED_ADDRESS);
00114                 defRoute->setGateway(IPAddress(par("gatewayIP").stringValue()));
00115                 defRoute->setInterface(IPAddressResolver().interfaceTableOf(destNode->getModule())->getInterfaceByName("tunDev"));
00116                 defRoute->setType(IPRoute::REMOTE);
00117                 defRoute->setSource(IPRoute::MANUAL);
00118                 IPAddressResolver().routingTableOf(destNode->getModule())->addRoute(defRoute);
00119 
00120                 IPRoute* gwRoute = new IPRoute();
00121                 gwRoute->setHost(IPAddress(par("gatewayIP").stringValue()));
00122                 gwRoute->setNetmask(IPAddress(255, 255, 255, 255));
00123                 gwRoute->setInterface(IPAddressResolver().interfaceTableOf(destNode->getModule())->getInterfaceByName("tunDev"));
00124                 gwRoute->setType(IPRoute::DIRECT);
00125                 gwRoute->setSource(IPRoute::MANUAL);
00126                 IPAddressResolver().routingTableOf(destNode->getModule())->addRoute(gwRoute);
00127             }
00128 
00129             // add route (with host=destNode) to every routing table in the network
00130             for (int j = 0; j < topo.getNumNodes(); j++) {
00131                 // continue if same node
00132                 if (i == j)
00133                     continue;
00134 
00135                 // cancel simulation if node is not connected with destination
00136                 cTopology::Node* atNode = topo.getNode(j);
00137 
00138                 if (atNode->getNumPaths() == 0) {
00139                     error((std::string(atNode->getModule()->getName()) + ": Network is not entirely connected."
00140                             "Please increase your value for the "
00141                             "connectivity parameter").c_str());
00142                 }
00143 
00144                 //
00145                 // Add routes at the atNode.
00146                 //
00147 
00148                 // find atNode's interface and routing table
00149                 IInterfaceTable* ift = IPAddressResolver().interfaceTableOf(atNode->getModule());
00150                 IRoutingTable* rt = IPAddressResolver().routingTableOf(atNode->getModule());
00151 
00152                 // find atNode's interface entry for the next hop node
00153                 int outputGateId = atNode->getPath(0)->getLocalGate()->getId();
00154                 InterfaceEntry *ie = ift->getInterfaceByNodeOutputGateId(outputGateId);
00155 
00156                 // find the next hop node on the path towards destNode
00157                 cModule* next_hop = atNode->getPath(0)->getRemoteNode()->getModule();
00158                 IPAddress next_hop_ip = IPAddressResolver().addressOf(next_hop).get4();
00159 
00160 
00161                 // Requirement 1: Each router has exactly one routing entry
00162                 // (netmask 255.255.0.0) to each other router
00163                 IPRoute* re = new IPRoute();
00164 
00165                 re->setHost(IPAddress(destAddr));
00166                 re->setInterface(ie);
00167                 re->setSource(IPRoute::MANUAL);
00168                 re->setNetmask(IPAddress(255, 255, 0, 0));
00169                 re->setGateway(IPAddress(next_hop_ip));
00170                 re->setType(IPRoute::REMOTE);
00171 
00172                 rt->addRoute(re);
00173 
00174                 // Requirement 2: Each router has a point-to-point routing
00175                 // entry (netmask 255.255.255.255) for each immediate neighbour
00176                 if (atNode->getDistanceToTarget() == 1) {
00177                     IPRoute* re2 = new IPRoute();
00178 
00179                     re2->setHost(IPAddress(destAddr));
00180                     re2->setInterface(ie);
00181                     re2->setSource(IPRoute::MANUAL);
00182                     re2->setNetmask(IPAddress(255, 255, 255, 255));
00183                     re2->setType(IPRoute::DIRECT);
00184 
00185                     rt->addRoute(re2);
00186                 }
00187 
00188                 // If destNode is the outRouter, add a default route
00189                 // to the next hop in the direction of the outRouter
00190                 if (strcmp(destNode->getModule()->getName(), "outRouter" ) == 0) {
00191                     IPRoute* defRoute = new IPRoute();
00192                     defRoute->setHost(IPAddress::UNSPECIFIED_ADDRESS);
00193                     defRoute->setNetmask(IPAddress::UNSPECIFIED_ADDRESS);
00194                     defRoute->setGateway(IPAddress(next_hop_ip));
00195                     defRoute->setInterface(ie);
00196                     defRoute->setType(IPRoute::REMOTE);
00197                     defRoute->setSource(IPRoute::MANUAL);
00198 
00199                     rt->addRoute(defRoute);
00200                 }
00201             }
00202         }
00203     }
00204     //access net configuration
00205     else if(stage == MAX_STAGE_UNDERLAY) {
00206         // fetch some parameters
00207         accessRouterNum = getParentModule()->par("accessRouterNum");
00208         overlayAccessRouterNum = getParentModule()->par("overlayAccessRouterNum");
00209 
00210         // count the overlay clients
00211         overlayTerminalCount = 0;
00212 
00213         numCreated = 0;
00214         numKilled = 0;
00215 
00216         // add access node modules to access node vector
00217         cModule* node;
00218         for (int i = 0; i < accessRouterNum; i++) {
00219             node = getParentModule()->getSubmodule("accessRouter", i);
00220             accessNode.push_back( node );
00221         }
00222 
00223         for (int i = 0; i < overlayAccessRouterNum; i++) {
00224             node = getParentModule()->getSubmodule("overlayAccessRouter", i);
00225             accessNode.push_back( node );
00226         }
00227 
00228         // debug stuff
00229         WATCH_PTRVECTOR(accessNode);
00230     }
00231 }

void InetUnderlayConfigurator::migrateNode ( NodeType  type,
TransportAddress addr = NULL 
) [virtual]

Migrates overlay nodes from one access net to another.

Parameters:
type the NodeType of the node to migrate
addr NULL for random node

Implements UnderlayConfigurator.

Definition at line 376 of file InetUnderlayConfigurator.cc.

00377 {
00378     Enter_Method_Silent();
00379 
00380     AccessNet* accessNetModule = NULL;
00381     int nodeID = -1;
00382     InetInfo* info;
00383 
00384     // If no address given, get random node
00385     if(addr == NULL) {
00386         info = dynamic_cast<InetInfo*>(globalNodeList->getRandomPeerInfo(type.typeID));
00387     } else {
00388         // get node information
00389         info = dynamic_cast<InetInfo*>(globalNodeList->getPeerInfo(*addr));
00390     }
00391 
00392     if(info != NULL) {
00393         accessNetModule = info->getAccessNetModule();
00394         nodeID = info->getNodeID();
00395     } else {
00396         opp_error("IPv4UnderlayConfigurator: Trying to pre kill node with nonexistant TransportAddress!");
00397     }
00398 
00399     // do not migrate node that is already scheduled
00400     if(scheduledID.count(nodeID))
00401         return;
00402 
00403     cModule* node = accessNetModule->removeOverlayNode(nodeID);//intuniform(0, accessNetModule->size() - 1));
00404 
00405     if(node == NULL)
00406         opp_error("IPv4UnderlayConfigurator: Trying to remove node which is nonexistant in AccessNet!");
00407 
00408     //remove node from bootstrap oracle
00409     globalNodeList->killPeer(IPAddressResolver().addressOf(node));
00410 
00411     node->bubble("I am migrating!");
00412 
00413     // connect the node to another access net
00414     AccessNet* newAccessNetModule;
00415 
00416     do {
00417         newAccessNetModule = check_and_cast<AccessNet*>(accessNode[intuniform(0, accessNode.size() - 1)]->getSubmodule("accessNet"));
00418     } while((newAccessNetModule == accessNetModule) && (accessNode.size() != 1));
00419 
00420     // create meta information
00421     InetInfo* newinfo = new InetInfo(type.typeID, node->getId(), type.context);
00422     // add node to a randomly chosen access net
00423     newinfo->setAccessNetModule(newAccessNetModule);
00424     newinfo->setNodeID(newAccessNetModule->addOverlayNode(node, true));
00425 
00426     //add node to bootstrap oracle
00427     globalNodeList->addPeer(IPAddressResolver().addressOf(node), newinfo);
00428 
00429     // inform the notification board about the migration
00430     NotificationBoard* nb = check_and_cast<NotificationBoard*>(node->getSubmodule("notificationBoard"));
00431     nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
00432 }

void InetUnderlayConfigurator::preKillNode ( NodeType  type,
TransportAddress addr = NULL 
) [virtual]

Notifies and schedules overlay nodes for removal.

Parameters:
type NodeType of the node to remove
addr NULL for random node

Implements UnderlayConfigurator.

Definition at line 309 of file InetUnderlayConfigurator.cc.

00310 {
00311     Enter_Method_Silent();
00312 
00313     AccessNet* accessNetModule = NULL;
00314     int nodeID;
00315     InetInfo* info;
00316 
00317     // If no address given, get random node
00318     if (addr == NULL) {
00319         addr = globalNodeList->getRandomAliveNode(type.typeID);
00320 
00321         if (addr == NULL) {
00322             // all nodes are already prekilled
00323             std::cout << "all nodes are already prekilled" << std::endl;
00324             return;
00325         }
00326     }
00327 
00328     // get node information
00329     info = dynamic_cast<InetInfo*>(globalNodeList->getPeerInfo(*addr));
00330 
00331     if (info != NULL) {
00332         accessNetModule = info->getAccessNetModule();
00333         nodeID = info->getNodeID();
00334     } else {
00335         opp_error("IPv4UnderlayConfigurator: Trying to pre kill node "
00336                   "with nonexistant TransportAddress!");
00337     }
00338 
00339     uint32_t effectiveType = info->getTypeID();
00340 
00341     // do not kill node that is already scheduled
00342     if(scheduledID.count(nodeID))
00343         return;
00344 
00345     cModule* node = accessNetModule->getOverlayNode(nodeID);
00346     globalNodeList->removePeer(IPAddressResolver().addressOf(node));
00347 
00348     //put node into the kill list and schedule a message for final removal of the node
00349     killList.push_front(IPAddressResolver().addressOf(node));
00350     scheduledID.insert(nodeID);
00351 
00352     overlayTerminalCount--;
00353     numKilled++;
00354 
00355     churnGenerator[effectiveType - 1]->terminalCount--;
00356 
00357     // update display
00358     setDisplayString();
00359 
00360     // inform the notification board about the removal
00361     NotificationBoard* nb = check_and_cast<NotificationBoard*>(
00362             node->getSubmodule("notificationBoard"));
00363     nb->fireChangeNotification(NF_OVERLAY_NODE_LEAVE);
00364 
00365     double random = uniform(0, 1);
00366 
00367     if (random < gracefulLeaveProbability) {
00368         nb->fireChangeNotification(NF_OVERLAY_NODE_GRACEFUL_LEAVE);
00369     }
00370 
00371     cMessage* msg = new cMessage();
00372     scheduleAt(simTime() + gracefulLeaveDelay, msg);
00373 
00374 }

void InetUnderlayConfigurator::setDisplayString (  )  [protected, virtual]

Updates the statistics display string.

Implements UnderlayConfigurator.

Definition at line 467 of file InetUnderlayConfigurator.cc.

Referenced by createNode(), and preKillNode().

00468 {
00469     char buf[80];
00470     sprintf(buf, "%i overlay terminals\n%i access router\n%i overlay access router",
00471             overlayTerminalCount, accessRouterNum, overlayAccessRouterNum);
00472     getDisplayString().setTagArg("t", 0, buf);
00473 }


Member Data Documentation

std::vector<cModule*> InetUnderlayConfigurator::accessNode [protected]

stores accessRouter

Definition at line 101 of file InetUnderlayConfigurator.h.

Referenced by createNode(), initializeUnderlay(), and migrateNode().

number of access router

Definition at line 70 of file InetUnderlayConfigurator.h.

Referenced by initializeUnderlay(), and setDisplayString().

std::deque<IPvXAddress> InetUnderlayConfigurator::killList [protected]

stores nodes scheduled to be killed

Definition at line 102 of file InetUnderlayConfigurator.h.

Referenced by handleTimerEvent(), and preKillNode().

number of overall created overlay terminals

Definition at line 106 of file InetUnderlayConfigurator.h.

Referenced by createNode(), finishUnderlay(), and initializeUnderlay().

number of overall killed overlay terminals

Definition at line 107 of file InetUnderlayConfigurator.h.

Referenced by finishUnderlay(), initializeUnderlay(), and preKillNode().

number of overlayAccessRouter

Definition at line 71 of file InetUnderlayConfigurator.h.

Referenced by initializeUnderlay(), and setDisplayString().

number of terminal in the overlay

Definition at line 72 of file InetUnderlayConfigurator.h.

std::set<int> InetUnderlayConfigurator::scheduledID [protected]

stores nodeIds to prevent migration of prekilled nodes

Definition at line 103 of file InetUnderlayConfigurator.h.

Referenced by handleTimerEvent(), migrateNode(), and preKillNode().


The documentation for this class was generated from the following files:
Generated on Wed May 26 16:21:17 2010 for OverSim by  doxygen 1.6.3