Configurator module for the InetUnderlay. More...
#include <InetUnderlayConfigurator.h>
Public Member Functions | |
TransportAddress * | createNode (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 |
Configurator module for the InetUnderlay.
Definition at line 41 of file InetUnderlayConfigurator.h.
TransportAddress * InetUnderlayConfigurator::createNode | ( | NodeType | type, | |
bool | initialize = false | |||
) | [virtual] |
Creates an overlay node.
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
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.
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.
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.
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 }
std::vector<cModule*> InetUnderlayConfigurator::accessNode [protected] |
stores accessRouter
Definition at line 101 of file InetUnderlayConfigurator.h.
Referenced by createNode(), initializeUnderlay(), and migrateNode().
int InetUnderlayConfigurator::accessRouterNum [private] |
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().
int InetUnderlayConfigurator::numCreated [protected] |
number of overall created overlay terminals
Definition at line 106 of file InetUnderlayConfigurator.h.
Referenced by createNode(), finishUnderlay(), and initializeUnderlay().
int InetUnderlayConfigurator::numKilled [protected] |
number of overall killed overlay terminals
Definition at line 107 of file InetUnderlayConfigurator.h.
Referenced by finishUnderlay(), initializeUnderlay(), and preKillNode().
int InetUnderlayConfigurator::overlayAccessRouterNum [private] |
number of overlayAccessRouter
Definition at line 71 of file InetUnderlayConfigurator.h.
Referenced by initializeUnderlay(), and setDisplayString().
int InetUnderlayConfigurator::overlayTerminalNum [private] |
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().